Как (если необходимо) освободить динамическую память при маршалинге CString из C ++ в C #? - PullRequest
2 голосов
/ 28 апреля 2010

У меня есть CString cs на стороне C ++ и IntPtr ip на стороне C #, которая содержит значение cs через механизм маршалинга.

Затем я просто получаю нужную строку как Marshal.PtrToStringAnsi (ip), и все работает нормально, но мне интересно, должен ли я и если должен, как я могу удалить неуправляемую память, занятую ip, т.е. cs?

Ответы [ 2 ]

1 голос
/ 28 апреля 2010

Вы не можете, вы не представляете, какой распределитель использовался неуправляемым кодом для создания экземпляра CString. Более того, вам нужно вызвать деструктор CString, вы не можете получить его адрес.

Вы мертвы в воде, если этот объект CString возвращается как возвращаемое функцией значение функции C ++, которую вы вызываете из C #. Это не ясно из вашего вопроса. У вас будет неуправляемая утечка памяти. Для решения этой проблемы потребуется оболочка, написанная на C ++ / CLI. Строки, возвращаемые как возвращаемые значения функции, должны быть выделены CoTaskMemAlloc () для правильной очистки маршалером P / Invoke. Ни один код C ++ никогда этого не делает.

1 голос
/ 28 апреля 2010

Неуправляемая память, выделенная неуправляемым кодом, может быть освобождена только неуправляемым кодом. Поэтому вам нужно добавить еще одну неуправляемую функцию, которая будет брать указатель на выделенную строку и освобождать память. Затем эту функцию следует вызывать из управляемого кода после завершения работы со строкой.

Пример:

class Program
{
    [DllImport("test.dll")]
    static extern IntPtr GetString();

    [DllImport("test.dll")]
    static extern IntPtr FreeString(IntPtr ptr);

    static void Main()
    {
        IntPtr ptr = GetString();
        try
        {
            var str = Marshal.PtrToStringAnsi(ptr);
            // work with the string
        } 
        finally 
        {
            if (ptr != IntPtr.Zero)
            {
                FreeString(ptr);
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...