使用SWIG通过C#调用MinGW编译的现有C DLL遇入口点错误求解决
解决SWIG包装MinGW编译的C DLL在C#中调用的EntryPointNotFoundException问题
看起来你已经走对了大部分流程,但遇到了符号绑定或调用约定相关的细节问题。结合MinGW和SWIG的特性,我整理了几个关键修复步骤:
1. 先确认架构完全匹配
你用-m32编译了32位DLL,但如果C#项目默认是Any CPU或x64架构,就会出现入口点找不到的问题:
- 右键你的C#项目 → 属性 → 生成 → 平台目标,选择x86
- 清理项目后重新生成,确保编译出的可执行文件是32位的
2. 修正包装DLL的编译方式
直接链接.dll文件可能导致MinGW无法正确解析符号(你看到的auto-import提示就是潜在风险信号),正确的做法是用导入库来链接:
步骤a:生成原DLL的导入库和def文件
如果没有mainDLL.def,先用MinGW的gendef工具生成:
gendef mainDLL.dll
然后用dlltool生成MinGW格式的静态导入库:
dlltool -d mainDLL.def -l libmainDLL.a
步骤b:重新编译SWIG包装文件
用导入库代替直接链接DLL,确保符号正确绑定:
gcc -shared -m32 example_wrap.c -L. -lmainDLL -o example.dll
(-L.表示在当前目录查找导入库,-lmainDLL对应生成的libmainDLL.a)
3. 检查并修正C#中的入口点与调用约定
即使Dependency Walker显示入口点存在,也可能因为调用约定或名字修饰不匹配导致找不到:
- 打开生成的
examplePINVOKE.cs,找到SWIGRegisterExceptionCallbacks_example的DllImport声明 - 确认EntryPoint的名称和工具(比如Windows SDK的
dumpbin /exports example.dll)看到的完全一致——MinGW编译的C函数可能带有下划线前缀(比如_SWIGRegisterExceptionCallbacks_example),如果是这样就修改EntryPoint - 加上调用约定声明,MinGW默认的C调用约定是
cdecl,确保和C#代码匹配:[DllImport("example", EntryPoint = "SWIGRegisterExceptionCallbacks_example", CallingConvention = CallingConvention.Cdecl)] public static extern void SWIGRegisterExceptionCallbacks_example(SWIGExceptionDelegate applicationDelegate, SWIGExceptionDelegate delegateDelegate);
4. 验证原DLL的导出符号
用工具确认原mainDLL.dll的函数确实被正确导出:
- 使用Windows SDK的
dumpbin /exports mainDLL.dll,或MinGW的nm -D mainDLL.dll - 确保你要调用的核心函数都在导出列表中,避免原DLL本身存在导出问题
额外优化:在SWIG接口文件中明确导出规则
确保你的example.i准确包含原DLL的头文件和要导出的符号,比如:
%module example %{ #include "example.h" // 替换成你的原DLL头文件路径 %} // 列出所有要导出的函数和变量 extern int My_variable; extern int fact(int n); extern int my_mod(int x, int y); extern char *get_time();
这样SWIG生成的包装代码会更准确,减少符号不匹配的概率
按照这些步骤重新操作后,应该就能解决找不到入口点的问题了。
内容的提问来源于stack exchange,提问作者mashrur
相关产品推荐
相关产品推荐

