如何指定是否拥有编组字符串的所有权?

假设我在C ++中有x.dll,它看起来像这样

MYDLLEXPORT
const char* f1()
{
   return "Hello";
}

MYDLLEXPORT
const char* f2()
{
   char* p = new char[20];
   strcpy(p, "Hello");
   return p;   
}

现在,假设我想在C#中使用它,

[DllImport("x.dll")]
public static extern string f1();

[DllImport("x.dll")]
public static extern string f2();

有什么办法可以告诉CLR对f2返回的字符串拥有强大的所有权,但不是f1? 问题在于,从f1返回的字符串最终会被GC释放,删除或其他任何事实,这同样不利于从f2返回的字符串。 希望问题清楚。 提前致谢


如果你对dll实现有任何影响,那么我强烈建议你不要像你在例子中展示的那样去做。 否则,请细化这个问题来提一下这个约束。

如果你必须从dll中返回一个堆分配的字符串,那么你还应该提供一个清理函数(当从dll导出动态分配的内存时总是很好的做法)。 你P / Invoke分配函数返回的IntPtr和编组与Marshal.PtrToString...在http://msdn.microsoft.com/en-us/library/atxe881w.aspx并完成通过调用事物本地方的清理功能。

另一种方法是使用BSTR (例如来自COM / Interop或P / Invoke的Marshaling BSTR):

本机:

__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 for C函数返回char *

链接地址: http://www.djcxy.com/p/51409.html

上一篇: How to specify whether to take ownership of the marshalled string or not?

下一篇: Select multiple values via CASE statement?