gpt4 book ai didi

python - 将 Python 扩展 (.pyd) 动态链接到另一个扩展

转载 作者:太空宇宙 更新时间:2023-11-03 12:10:18 28 4
gpt4 key购买 nike

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 时创建的对象文件 ( foo ) 解决了这个问题。被编译为 extra_objects扩展中的选项(仅当我在 foo 中定义了所有 bar 符号的原型(prototype)时才有效):

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 s,似乎在 bar 中重新定义了。我需要 PyTypeObject两个模块中的 s 引用相同的定义。)。

编辑 2: 所以,我挑出了这个问题。在我构建并链接导入库后,函数符号可以正确导出,但是 PyTypeObject正在重新申报。假设有一个 PyTypeOject Foo_Typefoo .我在 foo.h 中声明了它, 包含在 foo.c 中和 bar.c :

PyTypeObject Foo_Type;

我把它拿出来,放在 foo.c 的顶部附近:

PyTypeObject __declspec(dllexport) Foo_Type;

这靠近 bar.c 的顶部:

PyTypeObject __declspec(dllimport) Foo_Type;

这解决了问题。然后我可以在 foo 中使用 Foo_Type和 bar它引用了 Foo_Type 的相同定义。问题是,这不适用于非 Windows 系统。我假设如果我只是采取 __declspec出来了,它会在其他系统上正常工作。

最佳答案

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

关于python - 将 Python 扩展 (.pyd) 动态链接到另一个扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3269766/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com