Search ProofOfProgress Blog

Tuesday, August 8, 2017

CGO GoLang - First Time

I am not sure how CGO works, but for
whatever reason I need to OMIT including
implementation files for "go build" to
work. The code I am about to post will
fail if I add ncludes, giving an error
about "multiple inclusions"
--------------- main.go (start)--------------------
package main

/*
#include "whatever.h"

*/
import "C"
import "fmt"

//:It works, but I don't know why.
//:Removed include "whatever.c" and build works,
//:but not "go run". Linker just assumes that
//:existance of whatever.h means existance of
//:a whatever.c

//:03_CG_IS_NOT_GO.pdf suggests you can do
//:a forward declaration like so in golang code:
//:func myPrint(i C.int);

func main(){
    DoFoo();
}

//export myprint
func myprint(i C.int) {
 fmt.Printf("i = %v\n", uint32(i))
}

func DoFoo() {
 C.NotWorking()
}
--------------- main.go (end)----------------------

--------------- whatever.h (start)-----------------
#pragma once
#ifndef HEADER_DOT_H
#define HEADER_DOT_H
    extern void NotWorking();
    extern void myprint(int i);
    
    // Will get linker error if you uncomment
    // this. When commented out, " go build "
    // works, but "go run" fails.
    //
    // Go build is assuming that a 
    // "whatever.c" exists, even though I
    // do not mention it anywhere.
    //
    // XXX XXX #include "whatever.c" XXX XXX
    
#endif
--------------- whatever.h (end)-------------------

--------------- dontassume.c (start)---------------
#ifndef WHY_IS_THIS_NOT_WORKING
#define WHY_IS_THIS_NOT_WORKING

extern void myprint(int i);

void NotWorking() {
 int i;
 for (i=0;i<20;i++) {
  myprint(i);
 }
}


#endif

--------------- dontassume.c (end)-----------------

File Structure:
[Folder: export_func ]
   / dontassume.c
   / main.go
   / whatever.h

(  We have a folder called "export_func"    )
(  with the files, "dontassume.c" ,         )
(  "main.go", and "whatever.h" directly in  )
(  that folder.                             )

When you CD into export_func and run
$ go build
The result is an executable called
export_func.exe.

You can then run it via:
$ ./export_func.exe

Note: I am running go 1.8.1 on Windows 10.

If I #include dontassume.c in any of the
source files, the build will fail giving
me this erronious output:
JMIM@DESKTOP-JUDCNDL MINGW64 /g/MY_GOPATH/src/bitbucket.org/JMIM/JM_CGO/TEST01/export_func (master)
$ go build
# bitbucket.org/JMIM/JM_CGO/TEST01/export_func
C:\Users\JMIM\AppData\Local\Temp\go-build112659030\bitbucket.org\JMIM\JM_CGO\TEST01\export_func\_obj\main.cgo2.o:main.cgo2.c:(.text+0x0): multiple definition of `NotWorking'
C:\Users\JMIM\AppData\Local\Temp\go-build112659030\bitbucket.org\JMIM\JM_CGO\TEST01\export_func\_obj\_cgo_export.o:_cgo_export.c:(.text+0x0): first defined here
C:\Users\JMIM\AppData\Local\Temp\go-build112659030\bitbucket.org\JMIM\JM_CGO\TEST01\export_func\_obj\dontassume.o:dontassume.c:(.text+0x0): multiple definition of `NotWorking'
C:\Users\JMIM\AppData\Local\Temp\go-build112659030\bitbucket.org\JMIM\JM_CGO\TEST01\export_func\_obj\_cgo_export.o:_cgo_export.c:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

No comments:

Post a Comment