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.

Reply via email to