I wanna import a c-shared-library to go that generated by Cython in python 3.7, try do it by cgo.
in this case:
go version go1.12.7 linux/amd64
Python 3.7.3
Cython version 0.29.12
os: Manjaro 18.0.4
Kernel: x86_64 Linux 5.1.19-1
I will continue:
make a python file vim pylib.pyx
:
#!python
cdef public void hello():
print("hello world!")
and run python -m cython pylib.pyx
for generate the c-shared-library, I have two files, pylib.c
and pylib.h
.
now, try import these to golang, so make a go file vim test.go
:
package main
/*
#include </usr/include/python3.7m/Python.h>
#include "pylib.h"
*/
import "C"
import "fmt"
func main() {
C.hello()
fmt.Println("done")
}
finaly, I run go run test.go
:
I have the following output:
# command-line-arguments /usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_51159acd5c8e_Cfunc_hello': /tmp/go-build/cgo-gcc-prolog:48: undefined reference to `hello' collect2: error: ld returned 1 exit status
I try import it to c too but I encountered a similar output like this:
undefined reference to `hello' ld returned 1 exit status
I don't know what to do, help me, please. :(
I run go run test.go: I have the following output:
# command-line-arguments /usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_51159acd5c8e_Cfunc_hello': /tmp/go-build/cgo-gcc-prolog:48: undefined reference to `hello' collect2: error: ld returned 1 exit status
We can generate an equivalent error message with the following code.
package main
/*
#include <math.h>
*/
import "C"
import "fmt"
func main() {
cube2 := C.pow(2.0, 3.0)
fmt.Println(cube2)
}
Output:
$ go run cube2.go
# command-line-arguments
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_f6c6fa139eda_Cfunc_pow':
/tmp/go-build/cgo-gcc-prolog:53: undefined reference to `pow'
collect2: error: ld returned 1 exit status
$
In both cases, ld
(the linker) can't find a C function after looking in the usual places: undefined reference to 'pow'
or undefined reference to 'hello'
.
Let's tell cgo
where to find the C pow
function in the C math
library: m
.
For cgo
, using ld
flags,
#cgo LDFLAGS: -lm
-llibrary Search the library named library when linking.
Updating the previous code,
package main
/*
#cgo LDFLAGS: -lm
#include <math.h>
*/
import "C"
import "fmt"
func main() {
cube2 := C.pow(2.0, 3.0)
fmt.Println(cube2)
}
Output:
$ go run cube2.go
8
$
This illustrates a basic cgo
principle: include a C header file for your C library and point to the location of the C library.
References: