doume1301
2019-07-31 18:11 阅读 209
已采纳

导入cython生成的c共享库以与cgo一起使用

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. :(

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    doujia1988 doujia1988 2019-07-31 20:50

    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
    

    GCC: 3.14 Options for Linking

    -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:

    Cgo and Python : Embedding CPython: a primer

    点赞 评论 复制链接分享

相关推荐