可以将原生C ** char安全地传递给托管类型为“out string”的托管C#委托吗?

时间:2016-06-03 11:01:06

标签: c# pinvoke marshalling native managed

在C:

extern "C" __declspec(dllexport) int CfgGetVariableString(const char *Name, char **Value)
{
    char StrValue[STR_MAX];
    int RetValue = GetVariableToStrValue(Name, StrValue, STR_MAX);
    if (RetValue == 0)
        *Value = StrValue;

    return RetValue;
}

C#

[DllImport(DllName, CallingConvention = DllCallingConvention)]        
private static extern int CfgGetVariableString([MarshalAs(UnmanagedType.LPStr)]string name, [MarshalAs(UnmanagedType.LPStr)]out string value);

这不起作用。我可以通过调用CoTaskMemAlloc使其工作,但是我想我应该通过单独的托管到本机调用来释放它?

那么最干净的方法是什么?

1 个答案:

答案 0 :(得分:2)

  

我可以通过致电CoTaskMemAlloc来使其发挥作用。

这是它可以工作的唯一方式。因为编组器会调用CoTaskMemFree来释放从本机函数返回的内存。

  

我想我应该通过单独的托管到本机通话来释放它?

如上所述,这不是必需的,因为框架已经这样做了。

  

最干净的方法是什么?

在我看来,这里最干净的方法,因为你已经在编译时确定了一个字符串长度,就是让调用者分配内存。将类型从char**更改为char*。添加一个包含已分配字符串长度的额外参数。在C#端使用StringBuilder。这里有无数的这种模式的例子,实际上在其他地方也是如此,所以我觉得不需要添加到正典中。