开发者

Release SAFEARRAY from c++ DLL and c#

I have a c++ function that gets data and I called it from c#. The function gets a pointer to SAFEARRAY and poplate it with strings (using SysAllocString)

Everything is ok, but the program is leaking memory.

I did a little search and found that if I add this attribute to the method signature:

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

I need to release it in c++ code (where it was allocated), so I created this function

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

And in my dll i wrote this code

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); 
}

But i got an exception:

An unhandled exception of type 'Sys开发者_运维百科tem.AccessViolationException' occurred in Tester.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

What is wrong?


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜