i think cgo does some magic with defining functions called via C.funcname. if you have the same func defined in the C preamble as well as call it from the same Go file you get the same func defined twice. putting it elsewhere as an extern seems to work.
to be honest i never dug into it. i did it once for callbacks in a library in 2013 and forgot about it :) it just works. On Thu, Dec 5, 2019 at 9:52 PM Dan Kortschak <d...@kortschak.io> wrote: > > Thanks. Can you explain the reason for this so it sticks in my head? > > On Thu, 2019-12-05 at 21:03 -0700, andrey mirtchovski wrote: > > you just need to split it in two files. the cfuncs go into another > > (sorry for lack of playground link): > > > > $ go build cgo.go cfunc.go > > $ ./cgo > > Hello from stdio > > > > $ cat cgo.go > > package main > > > > /* > > #include <stdlib.h> > > extern void myprint(char *s); > > */ > > import "C" > > > > import "unsafe" > > > > //export Example > > func Example() { > > cs := C.CString("Hello from stdio\n") > > C.myprint(cs) > > C.free(unsafe.Pointer(cs)) > > } > > > > func main() { > > Example() > > } > > $ cat cfunc.go > > package main > > > > /* > > #include <stdio.h> > > #include <stdlib.h> > > > > void myprint(char* s) { > > printf("%s\n", s); > > } > > */ > > import "C" > > > > On Thu, Dec 5, 2019 at 8:47 PM Dan Kortschak <d...@kortschak.io> > > wrote: > > > > > > I am trying to write a shared module that will be called from C, > > > but I > > > have run into a problem in using the work-around in > > > https://github.com/golang/go/wiki/cgo#the-basics for calling > > > variadic C > > > functions. > > > > > > The case that I have is more complex, but altering the example at > > > the > > > wiki demonstrates the problem; the function definition that is used > > > to > > > call on to printf appears more than once in the C code generated by > > > Cgo. > > > > > > ``` > > > ~/src/github.com/kortschak/cgo $ cat cgo.go > > > package main > > > > > > /* > > > #include <stdio.h> > > > #include <stdlib.h> > > > > > > void myprint(char* s) { > > > printf("%s\n", s); > > > } > > > */ > > > import "C" > > > > > > import "unsafe" > > > > > > //export Example > > > func Example() { > > > cs := C.CString("Hello from stdio\n") > > > C.myprint(cs) > > > C.free(unsafe.Pointer(cs)) > > > } > > > > > > func main() {} > > > ~/src/github.com/kortschak/cgo $ go build -o cgo.so -buildmode=c- > > > shared > > > . > > > # github.com/kortschak/cgo > > > /tmp/go-build899365101/b001/_x002.o: In function `printf': > > > /usr/include/x86_64-linux-gnu/bits/stdio2.h:104: multiple > > > definition of > > > `myprint' > > > /tmp/go-build899365101/b001/_x001.o:/usr/include/x86_64-linux- > > > gnu/bits/stdio2.h:104: first defined here > > > collect2: error: ld returned 1 exit status > > > ``` > > > > > > Removing the "//export Example" comment prevents this failure, but > > > then > > > obviously also loses the exported function. I have tried protecting > > > the > > > function in a #ifndef/#endif, to no avail. > > > > > > Is it reasonable for me to expect this to work? If so, what am I > > > doing > > > wrong? > > > > > > thanks > > > Dan > > > > > > -- > > > You received this message because you are subscribed to the Google > > > Groups "golang-nuts" group. > > > To unsubscribe from this group and stop receiving emails from it, > > > send an email to golang-nuts+unsubscr...@googlegroups.com. > > > To view this discussion on the web visit > > > https://groups.google.com/d/msgid/golang-nuts/ab825669afe753c505952f18fb6c61bc8e2dd24d.camel%40kortschak.io > > > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAK4xykW1EiNZrXaytkrO%2BoiE4PQmF5ccDoc0b9aJgtMzXig8Bg%40mail.gmail.com.