【问题标题】:import c-shared library that generated by cython to go with cgo导入由 cython 生成的 c-shared 库与 cgo 一起使用
【发布时间】:2019-08-01 05:13:30
【问题描述】:

我想导入一个 c-shared-library 去使用 Cython 在 python 3.7 中生成的,尝试通过 cgo 来做。

在这种情况下:

go 版本 go1.12.7 linux/amd64

Python 3.7.3

Cython 版本 0.29.12

操作系统:Manjaro 18.0.4

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

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

【问题讨论】:

  • cgo 文档仅显示此功能与单行 cmets // 一起使用,您尝试过吗?
  • 这个问题太宽泛了。让我们从 cythonized 文件 .c/.h 不是共享对象这一事实开始。然后你也需要嵌入 python 解释器 - 列表还在继续......
  • @Jesse 感谢您的反馈 //#include "pylib.h" import "C" ... 所以我也有同样的问题。
  • This is the relevant section;它遵循与您在上面链接的问题中的 ead 回答相同的模式,例如,“main”函数包含许多您在此处忽略的内容。
  • @ead 我实际上并不认为它有那么广泛——我猜想熟悉 (C)Go 的人可以很快地翻译文档中的工作 C 示例。那个人肯定不是我。 (我对这个问题的问题是它似乎不是从这些例子开始的,所以有很多错误,但希望 OP 可以解决这个问题......)

标签: go gcc shared-libraries cython cgo


【解决方案1】:

我运行 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

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

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 to 'hello'

让我们告诉 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

【讨论】:

猜你喜欢
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多