Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Mac上的.Net Core StringBuilder编码_C#_C++_.net Core_Pinvoke - Fatal编程技术网

C# Mac上的.Net Core StringBuilder编码

C# Mac上的.Net Core StringBuilder编码,c#,c++,.net-core,pinvoke,C#,C++,.net Core,Pinvoke,我有以下C函数: LIBRARY_API HRESULT LA_CC GetRSAKeyPair(STRTYPE privateKeyPtr, STRTYPE publicKeyPtr) { int length = 2048; string privateKey, publicKey; if (GenerateRSAKeyPair(privateKey, publicKey) == false) { return FAIL; } #ifn

我有以下C函数:

LIBRARY_API HRESULT LA_CC GetRSAKeyPair(STRTYPE privateKeyPtr, STRTYPE publicKeyPtr)
{
    int length = 2048;
    string privateKey, publicKey;
    if (GenerateRSAKeyPair(privateKey, publicKey) == false)
    {
        return FAIL;
    }
#ifndef _WIN32
        *privateKeyPtr = '\0'; // assumes `dest_size > 0`
        strncat(privateKeyPtr, privateKey.c_str(), length);
        *publicKeyPtr = '\0'; // assumes `dest_size > 0`
        strncat(publicKeyPtr, publicKey.c_str(), length);
#else
        *privateKeyPtr = L'\0'; // assumes `dest_size > 0`
        wcsncat(privateKeyPtr, toUTF16(privateKey).c_str(), length);
        *publicKeyPtr = L'\0'; // assumes `dest_size > 0`
        wcsncat(publicKeyPtr, toUTF16(publicKey).c_str(), length);
#endif
    return OK;
}
使用pinvoke调用它:

[DllImport(DLL_FILE_NAME, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
 public static extern int GetRSAKeyPair(StringBuilder privateKey, StringBuilder publicKey);
使用时:

StringBuilder privateKey = new StringBuilder(2048);
StringBuilder publicKey = new StringBuilder(2048);
LibraryNative.GetRSAKeyPair(privateKey, publicKey);
Console.WriteLine(privateKey);
Console.WriteLine(publicKey);

输出以中文返回数据,尽管相同的代码在Windows上运行良好。本地库假设C++在非Windows平台上不是UTF—16,但StrugBuudor在NIX上也期望UTF 16。

可以在C++中的条件代码中找到解释。在这里,您选择在Windows以外的平台上使用8位编码,但在Windows上使用UTF16。另一方面,C代码通过使用

CharSet.Unicode
,明确表示文本为UTF16编码

这种不匹配可以解释您观察到的行为。如何修复它?好的,您需要确保接口的两侧(托管和非托管)使用相同的编码


你目前对不同平台采用不同编码的策略似乎给我带来了麻烦。这只会导致混乱。我的建议是为互操作选择一种编码。例如,UTF16将是一个合理的选择,它使互操作变得最简单,因为pinvoke封送员天生就理解它

@1201programalam toUTF16()不会在mac和linux上调用,它实际上会将字符串转换为wstring。代码似乎完全按照它所说的做。Windows上的Utf16,其他位置为8位。因此,你观察到的行为是意料之中的。您收到一个8位字符串,但将其解释为UTF16。你认为CharSet=CharSet.Unicode是什么意思?你为什么感到惊讶。此外,它是C++而不是C.@ DavidHeffernan上的Mac,我不将它转换成UTF16,本地代码假定它是8位字符串,但String Buube将其视为UTF16,我如何修复它?请再次阅读我的评论。特别是关于CharSet的部分。至于如何修复,谁知道呢。我们需要知道这个8位编码是什么。从这里看不清楚。但我们是我,我希望使用一致的编码。有一个函数在哪个平台上生成8位编码,而在另一个平台上生成16位编码,这是一个糟糕的设计。Windows将utf-16用于unicode,而Linux默认为utf-8,上面的代码编写时要记住,std::string类实际上意味着utf-8,我想.NetCore将在mac/Linux上对unicode使用utf-8。pinvoke marshaller使用您指定的编码,
CharSet=CharSet.unicode
,正如我在回答中所说的那样。没有
CharSet.UTF8
,所以在我看来,您最好在任何地方都使用
CharSet.UTF16
。顺便问一下,C++代码在Windows上使用什么编码。UTF-8还是ANSI?如果是后者,那么你可能还有其他问题。如果你不想在任何地方都使用UTF-16,那么你可能会在任何地方都选择UTF-8。但这反过来又使编组更加困难。没有
字符集.UTF8
。因此,您需要封送到一个字节数组中,并使用
Encoding.UTF8.GetString
解码为本机.net字符串。在Windows上,库使用wchar\u t和wstring,所有输入字符串都是wchat\t,对于Linux和Mac,它在内部使用char和string,所有输入都使用相同的字符和字符串,由于在这种特殊情况下,输出字符串应该是ascii base64编码键,因此我认为使用CharSet.Ansi应该可以工作,但对于输出字符串可以具有ascii以外的代码点的情况,我感到很困惑。支持不同的unicode编码肯定是一个错误的决定:(