Thanks, Ian and Andrey. On Thu, 2019-12-05 at 21:06 -0800, Ian Lance Taylor wrote: > On Thu, Dec 5, 2019 at 9:02 PM andrey mirtchovski < > mirtchov...@gmail.com> wrote: > > > > 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. > > That is basically right. > > This is documented at > https://golang.org/cmd/cgo/#hdr-C_references_to_Go: > > Using //export in a file places a restriction on the preamble: since > it is copied into two different C output files, it must not contain > any definitions, only declarations. If a file contains both > definitions and declarations, then the two output files will produce > duplicate symbols and the linker will fail. To avoid this, > definitions > must be placed in preambles in other files, or in C source files. > > Ian > > > > 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 > > .
-- 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/e35af66a53cc11e08ad97b5497b134f056354e01.camel%40kortschak.io.