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.
精彩评论