从c ++ DLL和c#发布SAFEARRAY

时间:2011-07-16 18:35:54

标签: c# c++ memory interop safearray

我有一个获取数据的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”类型异常

     

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

有什么问题?

1 个答案:

答案 0 :(得分:5)

我认为你应该尝试:

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

原因是您将strServerList声明为out,因此.Net封送处理器会尝试将指向无效(释放)内存的指针转换为字符串数组,这可能是挑起例外。