7

Python 扩展模块只是动态库,所以我认为可以将 Python 扩展动态链接到另一个。问题在于 Windows Python 扩展被赋予.pyd扩展名而不是.dll,所以当我运行安装脚本时,我无法让 distutils 链接到它们。(我认为这在 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创建的目标文件(fooextra_objectsfoobar

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"])

编译时没有抱怨,但某些符号存在一些问题(具体来说,我有一些全局PyTypeObjectsfoo似乎在 . 中重新定义bar。我需要PyTypeObject两个模块中的 s 引用相同的定义。)。

编辑2:所以,我挑出了问题。在我构建并链接到导入库后,函数符号正确导出,但PyTypeObjects 被重新声明。假设有一个PyTypeOject Foo_Typein 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_Type,foo并且bar它引用了 Foo_Type 的相同定义。问题是,这不适用于非 Windows 系统。我想如果我只是把__declspecs 拿出来,它会在其他系统上正常工作。

4

2 回答 2

2

如果您使用的是普通的 Python导入机制,则无需链接到其他扩展。如果你在另一个扩展中调用函数,大概是因为你已经获得了头文件,那么你需要从 DLL 生成一个导入库,然后才能链接它。

于 2010-07-17T04:51:32.623 回答
-3
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
    ]
);

来自: http: //pyd.readthedocs.io/en/latest/distutils.html

于 2017-10-20T06:00:18.897 回答