假设我在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(例如Marshaling BSTRs in COM/Interop or P/Invoke):
本机:
__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 function that returns char *上发现了类似的问题