调用DLL触发OSError: [WinError 193],疑C脚本问题求排查
问题排查:Python调用C DLL触发OSError: [WinError 193]
错误场景
调用C编译生成的DLL时出现错误:OSError: [WinError 193] %1 is not a valid Win32 application,已确认MinGW64安装,怀疑问题出在C代码,相关代码如下:
Python代码
import ctypes from numpy.ctypeslib import ndpointer lib = ctypes.CDLL(r"C:\Users\Ali\Desktop\test9\a.dll") lib.function.restype = ndpointer(dtype=ctypes.c_int, shape=(100000000,3), flags='C') res = lib.function() print(res)
C代码(DLL)
int (*function(void))[3] { clock_t begin = clock(); int (*information)[3] = malloc(100000000 * sizeof(*information)); for (int k = 0; k < 100000000; k++) { for (int j = 0; j < 3; j++) { information[k][j] = j; } } clock_t end = clock(); double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("%f\n", time_spent); return information; }
问题分析与解决
1. 位数不匹配(WinError 193核心原因)
WinError 193绝大多数情况是Python解释器位数与DLL编译位数不匹配:
- 检查Python位数:打开Python终端执行
import sys; print(sys.maxsize > 2**32),输出True为64位,False为32位。 - 对应位数编译DLL:
- 64位编译命令:
x86_64-w64-mingw32-gcc -shared -o a.dll your_c_code.c -lmsvcrt - 32位编译命令:
i686-w64-mingw32-gcc -shared -o a.dll your_c_code.c -lmsvcrt
- 64位编译命令:
2. C函数未导出
当前C代码中的function函数未标记为DLL导出符号,Python无法识别该函数,会导致加载失败或调用错误:
修改C代码添加导出声明,同时补充内存分配检查与输出缓冲刷新:
#include <stdio.h> #include <stdlib.h> #include <time.h> __declspec(dllexport) int (*function(void))[3] { clock_t begin = clock(); int (*information)[3] = malloc(100000000 * sizeof(*information)); if (!information) { // 避免内存分配失败返回空指针 fprintf(stderr, "Memory allocation failed\n"); return NULL; } for (int k = 0; k < 100000000; k++) { for (int j = 0; j < 3; j++) { information[k][j] = j; } } clock_t end = clock(); double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("Time spent: %f\n", time_spent); fflush(stdout); // 强制刷新输出,让Python能看到打印内容 return information; }
3. 内存泄漏问题
C代码中malloc分配了约1.2GB内存,Python无法自动释放,会导致内存泄漏:
添加内存释放函数并在Python中手动调用:
- C代码新增:
__declspec(dllexport) void free_memory(int (*ptr)[3]) { free(ptr); }
- Python代码修改:
import ctypes from numpy.ctypeslib import ndpointer lib = ctypes.CDLL(r"C:\Users\Ali\Desktop\test9\a.dll") lib.function.restype = ndpointer(dtype=ctypes.c_int, shape=(100000000,3), flags='C') lib.free_memory.argtypes = [ndpointer(dtype=ctypes.c_int, flags='C')] res = lib.function() print(res[:5]) # 打印前5行避免输出过载 lib.free_memory(res) # 手动释放内存
4. 编译优化建议
编译时添加-O2参数优化代码执行速度,避免1亿条数据初始化耗时过久:
x86_64-w64-mingw32-gcc -shared -o a.dll your_c_code.c -lmsvcrt -O2
内容的提问来源于stack exchange,提问作者user5963087
相关产品推荐
相关产品推荐

