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
个字符,则不会复制零。有很多解决方案:
- 使用提到的 wcscpy 复制带有 \0
的字符串
- 再复制一份
memcpy(OutName, out, (len + 1) * sizeof(wchar_t))
. 字符
此外,传递缓冲区 (StringBuilder) 大小是个好主意。 C/C++ 允许您编写外部变量边界。这个尺寸可以避免这种情况。
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
个字符,则不会复制零。有很多解决方案:
- 使用提到的 wcscpy 复制带有 \0 的字符串
- 再复制一份
memcpy(OutName, out, (len + 1) * sizeof(wchar_t))
. 字符
此外,传递缓冲区 (StringBuilder) 大小是个好主意。 C/C++ 允许您编写外部变量边界。这个尺寸可以避免这种情况。