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.

Reply via email to