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

标签 go gcc shared-libraries cython cgo

我想导入一个 c-shared-library 去 python 3.7 中由 Cython 生成的那个,试试用 cgo 做吧。

在这种情况下:

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

我会继续: 制作一个 python 文件 vim pylib.pyx:

#!python
cdef public void hello():
     print("hello world!")

并运行python -m cython pylib.pyx 来生成c-shared-library,我有两个文件,pylib.cpylib.h 。 现在,尝试将这些导入到 golang,所以制作一个 go 文件 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")
}

最后,我运行 go run test.go: 我有以下输出:

# 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

我也尝试将它导入到 c,但我遇到了类似这样的输出:

undefined reference to `hello'
ld returned 1 exit status

我不知道该怎么办,请帮帮我。 :(

最佳答案

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

我们可以使用以下代码生成等效的错误消息。

package main

/*
#include <math.h>
*/
import "C"
import "fmt"

func main() {
    cube2 := C.pow(2.0, 3.0)
    fmt.Println(cube2)
}

输出:

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

在这两种情况下,ld(链接器)在通常的地方查找后都找不到 C 函数:undefined reference to 'pow'对“你好”的 undefined reference

让我们告诉 cgo 在 C math 库中的哪里可以找到 C pow 函数:m

对于cgo,使用ld标志,

#cgo LDFLAGS: -lm

GCC: 3.14 Options for Linking

-llibrary
    Search the library named library when linking.

更新之前的代码,

package main

/*
#cgo LDFLAGS: -lm
#include <math.h>
*/
import "C"
import "fmt"

func main() {
    cube2 := C.pow(2.0, 3.0)
    fmt.Println(cube2)
}

输出:

$ go run cube2.go
8
$

这说明了一个基本的 cgo 原则:为您的 C 库包含一个 C 头文件并指向 C 库的位置。


引用资料:

Cgo and Python : Embedding CPython: a primer

关于go - 导入由 cython 生成的 c 共享库以与 cgo 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57296694/

相关文章:

python - 加载 Python 共享库时 C++ 中的 undefined symbol

go - Golang 中的大文件

go - 如何从 Go 中的 nslookup 获取 "Name"?

c++ - GTEST 中 std::map 和 dense_hash_map 的编译器错误

linux - 尝试将tcp init cwnd更改为10,但失败,我该怎么办

python - 从 python 脚本在共享库上运行 gcov

shared-libraries - 如何控制 Linux 上的共享库版本问题?

go - 为什么语音 REST API 响应与 go SDK API 响应不同?

google-app-engine - 使用 Golang 和 Standard Env 在 Google App Engine 上使用 urlfetch 添加 header 的正确方法

c - 使用 GCC 查找生成和终止集