У меня проблемы с утечкой памяти у стороннего c ++ dll. Для определенных вызовов dll выделяет память для строки, передает ее в виде символа * и затем ожидает получить этот указатель обратно, чтобы он мог отменить выделение памяти.
Вот некоторые комментарии из заголовочного файла, пара примеров, где возвращается символ *, и подпись метода «Release».
(DLL называется SW_API, она из торгового расчетно-кассового центра - если кто-нибудь, возможно, уже обернул это, я бы с удовольствием с ними поговорил!).
/* Strings returned by the API are similarly normal nul-terminated C strings.
* The user should not attempt to change any of the bytes or read past the
* terminating nul of any returned string. All returned strings must be
* released using SW_ReleaseString() once the user is finished with the
* result. Failure to do this will result in memory leaks.
*/
/**
* @typedef const char* SW_XML
* @brief A string containing an XML documents text.
* @note As with all output strings, returned XML must be freed
* by the user. See @ref resource.
* @sa ErrorCodes
*/
typedef const char* SW_XML;
const char* STDAPICALLTYPE SW_GetLastErrorSpecifics();
SW_ErrCode STDAPICALLTYPE SW_DealGetSWML(SW_LoginID lh,
const char* swmlVersion,
SW_DealVersionHandle dealVersionHandle,
SW_XML* resultXML_out);
void STDAPICALLTYPE SW_ReleaseString(const char* buffer);
Пытаясь прочитать из разных источников, я попробовал следующее:
// Extern declarations
[DllImport(sw_api_dll, EntryPoint = "_SW_GetLastErrorSpecifics@0", CharSet = CharSet.Ansi)]
public static extern IntPtr SW_GetLastErrorSpecifics();
[DllImport(sw_api_dll, EntryPoint = "_SW_DealGetSWML@16", CharSet = CharSet.Ansi)]
public static extern int SW_DealGetSWML(int lh, string swmlVersion, string dealVersionHandle, [Out] out IntPtr outputSWML);
[DllImport(sw_api_dll, EntryPoint = "_SW_ReleaseString@4", CharSet=CharSet.Ansi)]
public static extern void SW_ReleaseString(IntPtr buffer);
// Using the externs.
private static string GetIntPtrStringAndRelease(IntPtr ptr)
{
string result = Marshal.PtrToStringAnsi(ptr);
API.SW_ReleaseString(ptr);
return result;
}
public static int SW_DealGetSWML(int lh, string swmlVersion, string dealVersionHandle, ref string outputSWML)
{
IntPtr outputSWML_out = new IntPtr();
int result = API.SW_DealGetSWML(lh, swmlVersion, dealVersionHandle, out outputSWML_out);
outputSWML = GetIntPtrStringAndRelease(outputSWML_out);
return result;
}
public static string SW_GetLastErrorSpecifics()
{
IntPtr ptr = API.SW_GetLastErrorSpecifics();
return GetIntPtrStringAndRelease(ptr);
}
Кажется, я просто не могу получить API для освобождения строк.
Теперь, возможно, это просто ошибка в API, но я сомневаюсь в этом.
Скорее всего, я делаю что-то неправильно по ошибке.
Все, что я знаю, это то, что мой рабочий набор продолжает расти.
Рассматриваемая компания предоставляет оболочку Java, но не распространяется на оболочку .Net.
Любая помощь, полученная с благодарностью.
Бретт.