PInvoke和EntryPointNotFoundException

我无法理解下面的pinvoke有什么问题导致了EntryPointNotFoundException:

带有结构声明的C函数:

extern "C"__declspec (dllimport) __stdcall LONG NET_DVR_Login_V30 (char *sDVRIP, WORD wDVRPort, char *sUserName, char *sPassword, LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo); typedef struct { BYTE sSerialNumber[48]; BYTE byAlarmInPortNum; BYTE byAlarmOutPortNum; BYTE byDiskNum; BYTE byDVRType; BYTE byChanNum; BYTE byStartChan; BYTE byAudioChanNum; BYTE byIPChanNum; BYTE byZeroChanNum; BYTE byMainProto; BYTE bySubProto; BYTE bySupport; BYTE byRes1[20]; }NET_DVR_DEVICEINFO_V30, *LPNET_DVR_DEVICEINFO_V30; 

C#中的导入,结构声明和pinvoke:

  [DllImport("SDK.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] public extern static int NET_DVR_Login_V30( [MarshalAs(UnmanagedType.LPStr)] string sDVRIP, ushort wDVRPort, [MarshalAs(UnmanagedType.LPStr)] string sUserName, [MarshalAs(UnmanagedType.LPStr)] string sPassword, ref NET_DVR_DEVICEINFO_V30 lpDeviceInfo); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct NET_DVR_DEVICEINFO_V30 { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] public string sSerialNumber; public byte byAlarmOutPortNum; public byte byDiskNum; public byte byDVRType; public byte byChanNum; public byte byStartChan; public byte byAudioChanNum; public byte byIPChanNum; public byte byZeroChanNum; public byte byMainProto; public byte bySubProto; public byte bySupport; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string byRes1; } NET_DVR_DEVICEINFO_V30 deviceInfo = new NET_DVR_DEVICEINFO_V30(); int result = Functions.NET_DVR_Login_V30(ip, port, user, password, ref deviceInfo); 

我通过dumpbin检查了函数名称,并没有被破坏。 所以我想知道为什么会发生EntryPointNotFoundException,如果参数有任何问题,例如,会发生PInvokeStackImbalance错误,比如说。 任何想法这个pinvoke可能有什么问题?

有一个名为Dependency Walker( depends.exe )的工具,它将通过显示SDK.DLL的导入/导出表来帮助调试此问题 – 我会看一下。 可能 (这似乎让我怀疑)发生的另一件事是,因为你正在使用char *,.NET在你的函数名的末尾添加了一个“A”。 那可能是balderdash。

显然,名称不匹配。 因此,您需要确保接口的两端使用相同的名称:

  • 当从DLL导出函数作为stdcall时,它将被装饰。 您可以使用.def文件来避免此装饰。
  • 使用P / Invoke导入时,需要禁止添加WA后缀。 通过将DllImportAttributeExactSpelling字段设置为true