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/CAOyqgcXSy6UaOzJ1d_e_6R_crLcD23b%3DyUWMAVJLYFJ_fBr2MQ%40mail.gmail.com.

Reply via email to