cgo.go: multiple definition of `c_test_func'

281 views
Skip to first unread message

sbezverk

unread,
Oct 5, 2023, 6:14:04 PM10/5/23
to golan...@googlegroups.com

Hello,

 

I struggle to understand why this simple cgo program does not get linked, I would provide example in playground, but it does not seem to support cgo.

 

 

```
package main

 

// #include <stdio.h>

//

// extern int go_test_func(int c1, int c2);

//

// int c_test_func(int c1, int c2)

// {

//   return go_test_func(c1,c2);

// }

import "C"

 

import (

          "fmt"

)

 

//export go_test_func

func go_test_func(c1, c2 C.int) C.int {

          return c1 + c2

}

 

func main() {

          fmt.Printf("Result: %d\n", C.c_test_func(2, 2))

}
```

 

I am getting:

 

# command-line-arguments

/sw/packages/xr/go/1.19.4/pkg/tool/linux_amd64/link: running gcc failed: exit status 1

/tmp/go-link-349950461/000001.o: In function `c_test_func':

/nobackup/sbezverk/projects/go/worspace/cgo_test/cgo.go:9: multiple definition of `c_test_func'

/tmp/go-link-349950461/000000.o:/tmp/go-build/cgo.go:9: first defined here

collect2: error: ld returned 1 exit status

 

 

Thank you

Serguei

sbezverk

unread,
Oct 6, 2023, 1:53:55 AM10/6/23
to golan...@googlegroups.com

After looking in cgo generated files, I found that in fact function “c_test_func” is defined in 2 places.

 

1: ./cgo.cgo2.c:29: int c_test_func(int c1, int c2)

 

#line 3 "/nobackup/sbezverk/projects/go/worspace/cgo_test/cgo.go"

#include <stdio.h>

 

extern int go_test_func(int c1, int c2);

 

int c_test_func(int c1, int c2)

{

   return go_test_func(c1,c2);

}

 

2: ./_cgo_export.h:27: int c_test_func(int c1, int c2)

 

#line 3 "cgo.go"

#include <stdio.h>

 

extern int go_test_func(int c1, int c2);

 

int c_test_func(int c1, int c2)

{

   return go_test_func(c1,c2);

}

 

_cgo_export.h is included in  ./_cgo_export.c:4:#include "_cgo_export.h". Making it a second definition of the same function.

 

 

Is it a bug or what cgo.go does Go calling C func which in turn calls Go is not supported?

 

Thank you

Serguei

Ian Lance Taylor

unread,
Oct 6, 2023, 2:58:48 PM10/6/23
to sbezverk, golan...@googlegroups.com
On Thu, Oct 5, 2023 at 3:13 PM sbezverk <sbez...@gmail.com> wrote:
>
> I struggle to understand why this simple cgo program does not get linked, I would provide example in playground, but it does not seem to support cgo.
>
> ```
> package main
>
>
>
> // #include <stdio.h>
>
> //
>
> // extern int go_test_func(int c1, int c2);
>
> //
>
> // int c_test_func(int c1, int c2)
>
> // {
>
> // return go_test_func(c1,c2);
>
> // }
>
> import "C"
>
>
>
> import (
>
> "fmt"
>
> )
>
>
>
> //export go_test_func


Quoting from https://pkg.go.dev/cmd/cgo:

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
Reply all
Reply to author
Forward
0 new messages