Как указать, брать ли в собственность маршаллированную строку или нет? - PullRequest
7 голосов
/ 08 марта 2011

Предположим, у меня есть x.dll в C ++, который выглядит такстать владельцем строки, возвращенной из f2, но не из f1?Дело в том, что тот факт, что строка, возвращаемая из f1, в конечном итоге будет освобождена, удалена или что-либо еще с помощью GC, также плохо, потому что строка, возвращенная из f2, не будет.Надеюсь, вопрос был ясен.Заранее спасибо

1 Ответ

4 голосов
/ 09 марта 2011

Если вы имеете какое-либо влияние на реализацию dll, то я настоятельно рекомендую вам просто не делать этого так, как вы показали в своем примере. В противном случае, уточните вопрос, чтобы упомянуть это ограничение.

Если вам нужно вернуть выделенную кучу строку из dll, то вы также должны предоставить функцию очистки (всегда хорошая практика при экспорте динамически выделенной памяти из dll). Вы выполняете P / Invoke функции выделения с возвратом IntPtr и производите маршализацию с одним из Marshal.PtrToString... в http://msdn.microsoft.com/en-us/library/atxe881w.aspx и завершаете работу, вызывая функцию очистки для собственной стороны вещей.

Другой способ - использовать BSTR (пример из Маршалинг BSTR в COM / Interop или P / Invoke ):

Native:

__declspec(dllexport)
void bstrtest(BSTR *x)
{
    *x = SysAllocString(L"Something");
}

Управляется:

[DllImport("mydll.dll")]
extern static void bstrtest(ref IntPtr dummy);

static void Main(string[] args)
{
    var bstr = IntPtr.Zero;
    bstrtest(ref bstr);

    var text = Marshal.PtrToStringBSTR(bstr);
    Console.WriteLine(text);

    Marshal.FreeBSTR(bstr);
}

Я только что нашел похожий вопрос по SO: PInvoke для функции C, которая возвращает char *

...