可以将本机 C **char 安全地传递给参数类型为 "out string" 的托管 C# 委托吗?

can native C **char be safely passed to managed C# delegate with paramter type "out string"?

在 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 使其工作,但我想我应该通过单独的托管到本机调用来释放它?

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

I can make it work by calling CoTaskMemAlloc.

这是唯一可行的方法。因为编组器将调用 CoTaskMemFree 来释放从本机函数返回的内存。

I guess I should free it with separate managed to native call?

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

What is the cleanest way to do it?

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