Python扩展模块:链接两个扩展模块

时间:2014-12-11 15:59:33

标签: python c

我有两个用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.cbar.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') 文件以便不会发生此链接器错误?

0 个答案:

没有答案