Python扩展模块只是动态库,因此我假设可以将Python扩展动态链接到另一个。问题出在Windows上,Python Extensions被赋予.pyd
扩展名而不是.dll
,所以当我运行安装脚本时,我无法通过它来获取链接。 (我不认为这是UNIX上的问题,因为Python扩展使用.so
文件扩展名。)
假设我有一个扩展名bar.pyd
,需要链接到foo.pyd
。基本上,我在设置脚本中所做的是:
from distutils.core import setup, Extension
foo = Extension("foo", sources=["foo.c"])
bar = Extension("bar", libraries=["foo"], sources=["bar.c"])
setup(ext_modules=[foo, bar])
到目前为止,这不起作用。这甚至可能吗?我认为是,但我无法在网上找到任何东西。我在Windows上使用MinGW,但我希望这可以使用不同的MSVC ++以及其他系统。
编辑:之前,我通过将编译foo.o
时创建的目标文件(foo
)传递给扩展程序中的extra_objects
选项来解决此问题(这只有在我定义foo
中所有bar
符号的原型时才有效:
bar = Extension("bar", sources=["bar.c"], extra_objects=["build/.../foo.o"]
这似乎不是正确的解决方案,但它有效。我不明白动态链接,所以这可能是正确的方法。但是感觉非常错误。
然后,我尝试将一些显式参数传递给gcc,以使其编译导入库:
foo = Extension("foo", sources=["foo.c"], extra_compile_args=["-Wl,--out-implib,foo.lib,--export-all-symbols"])
然后我将bar
链接到新的导入库:
bar = Extension("bar", libraries=["foo"], sources=["bar.c"])
这是在没有投诉的情况下编写的,但是某些符号存在一些问题(具体来说,我在PyTypeObject
中有一些全局foo
似乎在bar
中重新定义了。我需要两个模块中的PyTypeObject
s引用相同的定义。)。
编辑2:所以,我挑出了这个问题。在我构建并链接到导入库之后,函数符号正确导出,但PyTypeObject
被重新声明。假设PyTypeOject Foo_Type
中有foo
。我在foo.h
中声明了它,它包含在foo.c
和bar.c
中:
PyTypeObject Foo_Type;
我把它拿出来,把它放在foo.c
的顶部附近:
PyTypeObject __declspec(dllexport) Foo_Type;
并且靠近bar.c
的顶部:
PyTypeObject __declspec(dllimport) Foo_Type;
解决了这个问题。然后我可以在foo
和bar
中使用Foo_Type,它引用了与Foo_Type相同的定义。问题是,这不适用于非Windows系统。我假设我只是把__declspec
取出来,它在其他系统上都能正常工作。
答案 0 :(得分:1)
如果您使用普通的Python import mechanisms,则无需链接到其他扩展程序。如果您在另一个扩展中调用函数,可能是因为您已经保留了头文件,那么您需要先从DLL生成一个导入库,然后才能链接它。
答案 1 :(得分:-1)
from distutils.core import Extension as cExtension
from pyd.support import setup, Extension
module1 = Extension("x", sources = ['xclass.c'])
module2 = Extension("y", sources = ['hello.d'], build_deimos=True)
setup(
name = "x",
version = '1.0',
description = "eat a taco",
ext_modules = [
module1,
module2
]
);