Python使用ctypes.CDLL调用DLL中libc函数时出现访问冲突问题
问题:加载自定义DLL调用libc函数触发访问违例
在Windows 11 64位系统下,使用Visual Studio 2022(或Cygwin-GCC、MinGW-GCC)编译自定义DLL,用Python 3.9.7的ctypes.CDLL加载后,DLL可正常加载,但调用malloc、strncpy等libc函数时触发访问违例错误。
最小复现代码
DLL代码(dllmain.cpp)
// dllmain.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung. #include "pch.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } #define DLLEXPORT extern "C" __declspec(dllexport) #include<stdlib.h> DLLEXPORT int exampl(void) { char* ex = (char*) malloc(100 * sizeof(char)); return(42); }
Python脚本(example.py)
import ctypes lib = ctypes.CDLL("example.dll", winmode=1) print(lib.exampl())
报错信息
python.exe .\example.py Traceback (most recent call last): File "*<some path>*\example.py", line 4, in <module> print(lib.exampl()) OSError: exception: access violation writing 0x0000000000002A3C
问题原因与解决方案
核心原因
问题出在C运行时库(CRT)的兼容性上:
- Python在Windows下默认使用微软的Visual C++ Runtime(UCRT),如果你的DLL使用静态链接CRT(如VS的
/MT选项)或MinGW/Cygwin自带的CRT,会导致DLL和Python使用独立的堆空间。malloc等内存分配函数依赖CRT的堆管理,跨CRT堆操作会直接触发访问违例。
具体解决步骤
Visual Studio编译设置
- 打开项目属性,进入「C/C++ → 代码生成」,将「运行库」设置为多线程DLL (/MD)(Debug版用
/MDd),确保DLL动态链接系统UCRT,和Python共享同一堆空间。
- 打开项目属性,进入「C/C++ → 代码生成」,将「运行库」设置为多线程DLL (/MD)(Debug版用
MinGW/Cygwin编译设置
- 编译时添加
-msvcrt选项,强制链接系统的MSVC CRT,而不是MinGW自带的libgcc。例如:g++ -shared -o example.dll dllmain.cpp -msvcrt
- 编译时添加
验证位数一致性
- 确保编译的DLL是64位版本,和Python的位数完全匹配(Python 3.9.7 64位对应64位DLL)。
内容的提问来源于stack exchange,提问作者broesel09-90
相关产品推荐
相关产品推荐

