Windows下ctypes加载C++类DLL报模块找不到,和MinGW编译器有关吗
DLL加载报错的根因与排查方案
报错提示中“(or one of its dependencies)”的描述表明,触发FileNotFoundError的原因通常不是单一的DLL路径错误,而是Windows加载器无法定位目标DLL本身、或DLL依赖的其他动态链接库。结合Windows环境下使用MinGW编译DLL的场景,按以下优先级排查即可解决:
基础排查步骤
- 核对实际文件路径:CLion默认的MinGW构建输出目录是
cmake-build-*对应子文件夹,很多时候编译生成的DLL并没有落到你代码里写的C:\Users\avishah\CLionProjects\Math\lib路径下。直接在资源管理器里定位生成的libpythonclass.dll,把实际绝对路径替换到CDLL的参数里,排除路径写错的问题。 - 校验架构匹配度:在Python交互环境执行
import platform; print(platform.architecture())确认Python是32位还是64位,确保编译DLL用的MinGW版本和Python架构完全一致——32位DLL无法被64位Python加载,反之亦然,这种场景下加载器也会统一报“找不到模块”的错误。
注意:当前报错发生在DLL加载的初期阶段,还未进入导出符号查找环节,因此你之前尝试添加
__declspec(dllexport)修饰的操作,对当前报错没有影响。如果是导出符号缺失的问题,报错会发生在加载完成后查找Foo_new函数时,而非初始化加载DLL的瞬间。
MinGW场景下的核心依赖问题
MinGW编译的DLL默认会动态链接自身的运行时库,这些库不在Windows系统搜索路径下,是这类报错最常见的诱因。你不需要强制更换MSVC,通过两种方式即可解决:
- 编译时开启静态链接,把运行时依赖直接打包进DLL,对应的编译参数为:
生成的DLL无需额外附带MinGW的运行时文件即可被正常加载。g++ -shared -o libpythonclass.dll your_source.cpp -static -static-libgcc -static-libstdc++ - 如果不使用静态链接,把MinGW安装目录下
bin文件夹内的libgcc_s_seh-1.dll、libstdc++-6.dll、libwinpthread-1.dll三个文件,和libpythonclass.dll放在同一文件夹下,Python加载时即可自动识别到这些依赖。
关于编译器选型的说明
- 不需要强制更换为MSVC,只要解决上述路径、架构、依赖三个问题,MinGW编译的DLL完全可以被ctypes正常调用。
- 如果选择换用MSVC编译,除了按要求给导出函数加
__declspec(dllexport)修饰,还要注意MSVC编译的DLL默认依赖对应版本的VC运行库,目标环境未安装对应版本的VC Redistributable时,依然会报同样的找不到依赖的错误。
加载成功后的必要代码修正
等DLL可以正常加载后,还需要补全ctypes的函数类型声明,否则64位环境下会出现指针截断导致程序崩溃:
- 指定
Foo_new的返回值为ctypes.c_void_p(默认返回int会截断64位指针) - 指定
Foo_bar的入参为ctypes.c_void_p
修正后的Python代码参考:
import ctypes # 替换为实际的DLL绝对路径 lib = ctypes.CDLL(r'C:\实际路径\libpythonclass.dll') # 补全函数类型声明 lib.Foo_new.restype = ctypes.c_void_p lib.Foo_new.argtypes = [] lib.Foo_bar.restype = None lib.Foo_bar.argtypes = [ctypes.c_void_p] class Foo(object): def __init__(self): self.obj = lib.Foo_new() def bar(self): lib.Foo_bar(self.obj)
内容的提问来源于stack exchange,提问作者Avi Shah
相关产品推荐
相关产品推荐

