9

我有一个获取数据的 c++ 函数,我从 c# 调用它。该函数获取指向 SAFEARRAY 的指针并用字符串填充它(使用 SysAllocString)

一切正常,但程序正在泄漏内存。

我做了一点搜索,发现如果我将此属性添加到方法签名中:

 [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
 out string[] strServerList

我需要在 C++ 代码中发布它(它被分配的地方),所以我创建了这个函数

 [DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "DeallocateExternal")]
 internal static extern void DeallocateExternal(
 [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
 out string[] strServerList);

在我的 dll 中我写了这段代码

void DeallocateExternal(SAFEARRAY** psa)
{
    LONG cDims = SafeArrayGetDim(*psa);
    BSTR* pvData = (BSTR*)((*psa)->pvData); 
    for (LONG x = 0; x < cDims; x++)
    {
       SysFreeString(pvData[x]);
    }
    SafeArrayDestroy(*psa); 
}

但我有一个例外:

Tester.exe 中发生了“System.AccessViolationException”类型的未处理异常

附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。

怎么了?

4

1 回答 1

5

I think you should try:

...
SafeArrayDestroy(*psa); 
*psa = NULL
...

The reason for this is that you are declaring strServerList as out, so the .Net marshaler will try to convert a pointer to an invalid (freed) memory into an array of string, which may provoke the exception.

于 2011-07-26T20:37:20.797 回答