stringbuilder 作为输出参数

stringbuilder as out parameter

extern "C"
__declspec(dllexport)
bool FillString(LPWSTR OutName)
{
    LPWSTR out = L"TheName[=10=]";
    int len = wcslen(out);
    memcpy(
                OutName,
                out,
                len * sizeof(wchar_t));
    return true;
}

这是我的 c/c++ dll 中的函数,以下是我从 c# 中调用...

[DllImport(@"My.dll", EntryPoint = "FillString", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool MyFunction([MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder Name);

var fromdll = new StringBuilder(64); 
// I do not know length of out string (Name), but it is null terminated

bool IsFilled = MyFunction(fromdll);

Console.WriteLine(fromdll);

输出为

TheName???

谁能帮我得到输出...?

TheName

您需要再复制一个字符。 '[=10=]' 称为字符串终止符。没有它,.NET 中的 C、C++ 和 PInvoke 无法识别字符串结尾。如果要复制 wcslen 个字符,则不会复制零。有很多解决方案:

  1. 使用提到的 wcscpy 复制带有 \0
  2. 的字符串
  3. 再复制一份 memcpy(OutName, out, (len + 1) * sizeof(wchar_t)).
  4. 字符

此外,传递缓冲区 (StringBuilder) 大小是个好主意。 C/C++ 允许您编写外部变量边界。这个尺寸可以避免这种情况。