加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 07:54:55 所属栏目:百科 来源:网络整理
导读:假设我在C中有x.dll,看起来像这样 MYDLLEXPORTconst char* f1(){ return "Hello";}MYDLLEXPORTconst char* f2(){ char* p = new char[20]; strcpy(p,"Hello"); return p; } 现在,假设我想在C#中使用它 [DllImport("x.dll")]public static extern string f1()
假设我在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 *上发现了类似的问题

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读