我有两个用C编写的Python扩展模块。每个模块使用在C中定义新Python类型的标准方法定义一个类型:
// in foo.c:
//
struct Foo
{
PyObject_HEAD;
int x;
int y;
int z;
};
PyTypeObject FooType = {
PyObject_HEAD_INIT,
0,
"Foo",
sizeof(Foo),
... etc ...
};
现在,我有第二个Python扩展模块(同一个软件包的一部分),名为Bar
(在bar.c
中创建),它使用Foo
个实例。因此,我创建了一个公共头文件,其中将定义struct Foo
,并且我还声明了:
extern PyTypeObject FooType;
我之所以这样做是因为我想让FooType
符号可用于bar.c
,以便进行重要的类型检查。在bar.c
中,我希望能够说:
void Foo_TypeCheck(PyObject* obj)
{
return (PyTypeObject*) (PyObject_Type(obj)) == &FooType;
}
...以便我可以确认bar.c
中使用的某个对象实际上是FooType
的实例。我需要能够私下访问Foo
实例中的内部数据成员,因此我必须检查PyObject是否实际上是FooType
的实例。
但是...
使用标准的disutils工作流程,当我在Python中实际导入Bar
模块时,会出现链接错误。基本上,我有两个扩展模块foo.c
和bar.c
,我使用disutils构建两个模块(作为同一个包的一部分)。我有一个公共头文件foo.h
,它定义struct Foo
,前向声明FooType
。但是当编译bar.c
时,我收到一个链接器错误,抱怨FooType
的未定义符号。当然,原因很清楚:bar.c
可以访问头文件 foo.h
,但它实际上并不与{{{}创建的共享对象文件相关联。 1}},因此它没有看到foo.c
的实现。
我的FooType
文件很简单:
setup.py
那么,如何编写foo_module = Extension('mypackage.foo', sources = ['foo.c'])
bar_module = Extension('mypackage.bar', sources = ['bar.c'])
setup(name = 'blah', ext_modules = [foo_module, bar_module], packages = 'mypackage')
文件以便不会发生此链接器错误?