【问题标题】:Dynamic module does not define module export function(PyInit_example)动态模块没有定义模块导出函数(PyInit_example)
【发布时间】:2021-12-23 05:49:03
【问题描述】:

我最近正在使用 swig 为 python 构建一个 C 扩展

一开始,我跑了:

swig -python example.i

然后它生成example.py & example_wrap.c

我跑了之后:

gcc -c example.c example_wrap.c -I D:/path_to_python/Python/include

好的,那么它生成了对象 example.o & example_wrap.o

我想制作一个共享对象文件并运行后:

gcc -o example.dll -s -shared example.o -Wl,--subsystem,windows

它生成了example.dll。 我将example.dll的扩展名重命名为example.pyd。然后将example.pydexample.py分别复制并粘贴到Python\DLLsPython\Lib文件夹。

直到一切顺利。 但是当我打开python.exe 并写import example 时会出现错误。它说:

Dynamic module does not define module export function(PyInit_example).

我尝试了各种方法,但没有成功。我想从.dll 生成.pyd

我用过:

-Windows 10

-Python310

-GCC MinGW 64

我感谢那些提供帮助的人。

【问题讨论】:

  • 最终名称应为_example.pyd(带下划线)。你 import example 加载 example.py,然后加载 import _example

标签: python c windows swig


【解决方案1】:

最终名称应为_example.pyd(带下划线)。你import example 加载生成的example.py,然后执行import _example 并加载_example.pyd。无需将任何内容复制到 Python 子目录中。

确保example.i 文件以%module example 开头。

我没有安装 MingGW,但这是使用 VS2019 构建的命令行:

example.i

%module example

%inline %{
int add(int a, int b) {
    return a + b;
}
%}

下面的演示。注意/Fe 命名输出文件,/LD 创建一个 DLL。

C:\demo>swig -python example.i

C:\demo>cl /LD /Fe_example.pyd /Ic:\python38\include example_wrap.c -link -libpath:c:\python38\libs
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30136 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

example_wrap.c
Microsoft (R) Incremental Linker Version 14.29.30136.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/dll
/implib:_example.lib
/out:_example.pyd
-libpath:c:\python38\libs
example_wrap.obj
   Creating library _example.lib and object _example.exp

C:\demo>py
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.add(5,6)
11

这是我对 MingGW 的最佳猜测(未经测试,因为我没有安装它):

swig -python example.i
gcc -c -fpic example.c example_wrap.c -Ipython3.9
gcc -shared example.o example_wrap.o -o _example.pyd

【讨论】:

  • 直接将example.dll重命名为example.pyd可以吗?
  • @Chetan 我通常使用编译器开关来命名最终结果,但没有理由直接重命名不起作用。
  • @Chetan 您的链接步骤也必须包含example_wrap.oadd_basic.o 是不是打错字了?
  • 那我该怎么办呢?我希望它像其他标准 python 模块一样运行,而不是使用 ctypes.CDLL()。
  • @Chetan ctypes 与 swig 无关。将example.py_example.pyd 与脚本放在同一目录中后,只需import example
猜你喜欢
  • 1970-01-01
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 2019-09-09
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多