在 P/Invoking 时处理调用函数的第三方库会导致堆损坏

Dealing with a 3rd party library who's function call causes heap corruptions when P/Invoking

我创建了一个调用 FlexNet Publisher 的库包装器。它是用 C 语言编写的。我正在尝试 P/Invoke 它:

[DllImport("lmgr11.dll")]
public static extern void free_job();

它的实现相当简单:

void WINAPI free_job()
{
    if (jobPtr != NULL)
        lc_free_job(jobPtr);
    jobPtr = NULL;
}

文档说 lc_free_job 应该释放作业以及所有资源。从本机代码调用 lc_free_job 工作得很好(我让一个 ATL 对象通过一个 COM 对象向它公开了一个包装器,我可以整天从 Visual C++ 控制台应用程序使用这个方法,所以我知道它必须工作) .

但是,在 C# 中,当我尝试 P/Invoke 此方法时,出现以下错误,导致我的应用程序崩溃:

Unhandled exception at 0x00007FFA39358283 (ntdll.dll) in CerberusTestHarness.exe: 0xC0000374: A heap has been corrupted (parameters: 0x00007FFA393AF6B0).

这是为什么?我可以抓住它或以任何方式规避它吗?如果我将调用包装在 try-catch 中,我似乎无法捕获异常,因为它不会抛出 .NET 异常。请注意,我没有 lc_free_job 的源代码,因此很遗憾,我无法检查或查看其源代码。它是用 C 写的。

问题是由于我的 C# P/Invoke 代码来自之前的调用。希望这对遇到同样问题的其他人有所帮助。

我已经定义了这个 P/Invoke 以从 returns char *:

的函数中获取错误字符串
[DllImport("lmgr11.dll")]
public static extern string errstring();

每当我的第 3 方库出现故障时,我都会调用它,如上所述。这不是 P/Invoke 的正确方法 returns char * 的方法。否则,当从本机端释放错误时,由于此字符串的编组方式将导致堆损坏。

需要这样定义:

[DllImport("lmgr11.dll")]
public static extern IntPtr errstring();

并调用如下:

var errorMessage = Marshal.PtrToStringAnsi(errstring());