我有一个供应商的 API 调用,我想在我的 C# Windows 窗体应用程序中使用它。问题是,无论我尝试什么P/Invoke,我都会在线路上崩溃,说明调用使堆栈不平衡。我尝试与供应商合作,但他们没有 Visual Studio 2012,也没有任何 C# 或.NET经验,经过几次来回电子邮件,他们基本上解决了问题。
这是他们的官方 C/C++ 声明
const char *<dll name here>(int Param1,
const char *Param2,
const char *Param3,
unsigned long Param4,
unsigned short Param5,
unsigned short Param6,
unsigned short Param7,
unsigned short Param8,
unsigned short Param9);
这是我尝试过的最近的 P/Invoke DLLImport 行。
[System.Runtime.InteropServices.DllImport(
"<dll name here>", EntryPoint = "<AnsiFunctionName>", ExactSpelling = true,
CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
public static extern String <AnsiFunctionName>(int Param1,
String Param2,
String Param3,
ulong Param4,
Int16 Param5,
Int16 Param6,
Int16 Param7,
Int16 Param8,
Int16 Param9);
这是实际的错误消息:
主题行:检测到 PInvokeStackImbalance
调用 P/Invoke 函数 '' 使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 P/Invoke 签名的调用约定和参数是否与目标非托管签名匹配。
我尝试了各种方法,甚至设置了一个 void 返回类型。我尝试不使用返回类型。我尝试代替 Strings、StringBuilders 和 IntPtrs。无论我尝试了什么,都没有任何效果。
在阅读 Stack Overflow 上的一篇文章后,我向供应商提到返回字符串是危险的,永远不应该这样做。他们的回应是:
“该页面上提到的字符串返回问题不适用于我们的函数。它们返回指向静态分配字符串的指针,因此您不需要释放它(并且不能尝试这样做)。看起来像“UnmanagedType.LPStr”应该可以工作(尽管 IntPtr 的东西也应该可以工作,通过适当的转换或转换)。
更新#1:正如评论中提到的,在这篇文章之前,我一直在使用 uint,而不是 ulong。我只是认为我让比较看起来更好。uint 和 ulong 都不起作用。
更新 #2:也许给出实际的函数名称会有所帮助。它是犰狳 CreateCodeShort3A。展望未来,我使用的是纯 .NET,但我仍然需要与之交互,只是目前还不太可能。不仅如此,这个问题让我很好奇为什么我不能解决像 P/Invoke 这样看似简单的问题。毕竟,有多少种变化?(不是一个严肃的问题)。