C#调用C++ DLL报错0x8007000B,疑为字符串传参问题求解答
C#调用C++ DLL抛出"加载格式错误"异常解决办法
我开发的C#程序需要调用C++编写的DLL,运行时抛出错误:An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)。怀疑是结构体中char *pcAddrs的字符串传递出了问题,求解决办法。
相关代码信息
C++ DLL定义
typedef struct CommIfInfo { char *pcAddrs; long lPortNo; long lRetry; long lSendTimeOut; long lCommSide; long lMode; long lKind; } COMMIF_INFO; // 需要调用的函数 int Open( COMMIF_INFO *pInfo )
原始C#代码
// DLL导入 [DllImport("Open-IF.dll", CallingConvention = CallingConvention.StdCall)] public static extern int Open(COMMIFINFO info); // 结构体定义 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct COMMIFINFO { [MarshalAs(UnmanagedType.LPStr)] public string ip; public int PortNo; public int Retry; public int SendTimeOut; public int CommSide; public int Mode; public int Kind; } private void button1_Click(object sender, EventArgs e) { string _ip = "192.168.1.1"; COMMIFINFO info = new COMMIFINF(); info.ip = _ip; info.Kind = 1; int ErrCode = Open(info); }
错误原因&修复步骤
1. 优先排查平台不匹配问题
这个0x8007000B异常绝大多数情况是平台位数不兼容:
- 如果C++ DLL是32位编译的,C#程序却跑在64位环境(或者反过来),直接就会触发这个错误。
- 解决:右键C#项目→属性→生成→平台目标,改成和C++ DLL一致的位数(32位选
x86,64位选x64,别用Any CPU)。
2. 修正P/Invoke的调用约定&参数传递
- C++默认的函数调用约定是
cdecl,你代码里写成了StdCall,会导致栈调用错误。 - C++函数接收的是结构体指针(
COMMIF_INFO *pInfo),但你C#里传的是值类型,必须加ref关键字传递引用。 - 结构体字段名尽量和C++保持一致,避免混淆;同时修正实例化时的拼写错误(
COMMIFINF→COMMIFINFO)。
3. 修正后的完整C#代码
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct COMMIF_INFO { [MarshalAs(UnmanagedType.LPStr)] public string pcAddrs; // 和C++字段名统一 public int lPortNo; public int lRetry; public int lSendTimeOut; public int lCommSide; public int lMode; public int lKind; } // 修正调用约定为cdecl,添加ref传递结构体引用 [DllImport("Open-IF.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int Open(ref COMMIF_INFO pInfo); private void button1_Click(object sender, EventArgs e) { string _ip = "192.168.1.1"; COMMIF_INFO info = new COMMIF_INFO(); info.pcAddrs = _ip; info.lKind = 1; // 记得给其他必要字段赋值,比如lPortNo等,避免传递未初始化的垃圾数据 int ErrCode = Open(ref info); }
内容的提问来源于stack exchange,提问作者TK.C
相关产品推荐
相关产品推荐

