Mam funkcję C++, która pobiera dane i nazwałem ją z C#. Funkcja uzyskuje wskaźnik do SAFEARRAY i przesyła ją naprzemiennie za pomocą łańcuchów (przy użyciu SysAllocString).Release SAFEARRAY z C++ DLL i C#
Wszystko jest w porządku, ale program jest nieszczelny.
Zrobiłem trochę szukanie i okazało się, że jeśli dodać ten atrybut do podpisu metoda:
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
out string[] strServerList
muszę zwolnić go w C++ kod (gdzie została przydzielona), więc stworzyłem tę funkcję
[DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "DeallocateExternal")]
internal static extern void DeallocateExternal(
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
out string[] strServerList);
I w moim DLL napisałem ten kod
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);
}
ale mam wyjątek:
nieobsługiwany wyjątek typu „System.AccessViolationException” wystąpił w Tester.exe
Dodatkowe informacje: Nastąpiła próba odczytu lub zapisu pamięci chronionej. Często jest to wskazówką, że inna pamięć jest uszkodzona.
Co jest nie tak?
należy użyć SafeArrayGetUBound zamiast SafeArrayGetDim zobacz http://msdn.microsoft.com/en-us/library/aed339d5-d962-4adc-ac01-6c15a54c51ca%28VS.85%29 – Yahia