2010-04-28 1 views
2

У меня есть CString cs на стороне C++ и IntPtr ip на стороне C#, которая содержит значение cs через механизм маршалинга.Как (если необходимо) освободить динамическую память при маршалинге CString с C++ на C#?

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

ответ

1

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

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

1

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

Пример:

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

SO, вы говорите, что на стороне C++, что функция должна выглядеть следующим образом: CString FreeString (CString CS) {...} Если дело обстоит именно так, как эта функция должна быть реализована? –

+0

Нет, он должен выглядеть как 'void FreeString (CString cs)'. Что касается реализации, может быть, какой-то эксперт на С ++ может дать свои два цента. –

 Смежные вопросы

  • Нет связанных вопросов^_^