【问题标题】:Why isn't go build finding Py_None?为什么 go build 找不到 Py_None?
【发布时间】:2017-04-02 23:35:00
【问题描述】:

我正在为 Python 包装一个 Go 库。我需要能够返回 None,但在编译时找不到它:

/*
#cgo pkg-config: python3
#define Py_LIMITED_API
#include <Python.h>
*/
import "C"

//export Nothing
func Nothing(self, args *C.PyObject) (status *C.PyObject) {
    C.Py_IncRef(C.Py_None)
    return C.Py_None
}

这是go build的输出

go build -buildmode=c-shared -o mymodule.so
# example.com/mywrapper
/tmp/go-build293667616/example.com/mywrapper/_obj/_cgo_main.o:(.data.rel+0x0): undefined reference to `Py_None'
collect2: error: ld returned 1 exit status

我不明白它如何找到所有其他 Py* 函数和类型(PyArgs_ParseTuplePyLong_FromLong 工作得很好),但找不到 Py_None。 Python 库显然正在加载。这是怎么回事?

【问题讨论】:

  • 看起来Py_None 是一个宏:github.com/python/cpython/blob/…
  • 哇,我从来没想到过。你到底应该如何从 Go 返回 None ?这肯定是有人碰到的东西……
  • 我对cgo一无所知,但想必你可以通过某种方式参考_Py_NoneStruct的地址,也就是Py_None的扩展地址。

标签: python python-3.x go cgo


【解决方案1】:

感谢Ismail Badawi 的评论,答案是用C 编写一个返回None 的函数。这是必需的,因为 Py_None 是一个宏,Go 看不到。

none.c

#define Py_LIMITED_API
#include <Python.h>

PyObject *IncrNone() {
        Py_RETURN_NONE;
}

mymodule.go

/*
#cgo pkg-config: python3
#define Py_LIMITED_API
#include <Python.h>

PyObject *IncrNone();
*/
import "C"

//export Nothing
func Nothing(self, args *C.PyObject) (status *C.PyObject) {
        return C.IncrNone()
}

【讨论】:

    猜你喜欢
    • 2012-06-26
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 2016-11-27
    相关资源
    最近更新 更多