2016-11-19 91 views
1

我正在为Python编写一个Go库。我需要能够返回无,但它不是在编译时发现它:为什么不去建立Py_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库显然正在加载。这里发生了什么?

+3

貌似'Py_None'是一个宏:https://github.com/python/cpython/blob/ 321fd597f9dff757185bcfeb5fc39536746e06ab/Include/object.h#L908 –

+0

哇,我永远不会猜到这一点。你怎么应该从Go回来没有?当然,这是有人碰到的东西... –

+0

我不知道cgo的任何事情,但大概你可以以某种方式引用'_Py_NoneStruct'的地址,这是'Py_None'扩展到的地址。 –

回答

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() 
}