c# – 如何指定是否取得编组字符串的所有权?

前端之家收集整理的这篇文章主要介绍了c# – 如何指定是否取得编组字符串的所有权?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设我在C中有x.dll,看起来像这样
  1. MYDLLEXPORT
  2. const char* f1()
  3. {
  4. return "Hello";
  5. }
  6.  
  7. MYDLLEXPORT
  8. const char* f2()
  9. {
  10. char* p = new char[20];
  11. strcpy(p,"Hello");
  12. return p;
  13. }

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

  1. [DllImport("x.dll")]
  2. public static extern string f1();
  3.  
  4. [DllImport("x.dll")]
  5. 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(例如Marshaling BSTRs in COM/Interop or P/Invoke):

本机:

  1. __declspec(dllexport)
  2. void bstrtest(BSTR *x)
  3. {
  4. *x = SysAllocString(L"Something");
  5. }

管理:

  1. [DllImport("mydll.dll")]
  2. extern static void bstrtest(ref IntPtr dummy);
  3.  
  4. static void Main(string[] args)
  5. {
  6. var bstr = IntPtr.Zero;
  7. bstrtest(ref bstr);
  8.  
  9. var text = Marshal.PtrToStringBSTR(bstr);
  10. Console.WriteLine(text);
  11.  
  12. Marshal.FreeBSTR(bstr);
  13. }

我刚刚在SO:PInvoke for C function that returns char *上发现了类似的问题

猜你在找的C#相关文章