通过CLI在1256编码中将字符串从C#传递到本机C ++库

时间:2016-11-09 14:11:41

标签: c# string encoding c++-cli

我必须在C#项目(.Net Framework 4)中使用旧的C ++库。

一般来说,我已经设置并运行了所有内容,但是将字符串值传递给库会给我带来麻烦。

我在utf-8中收到包含阿拉伯字符的字符串值。 该库正在处理iso-1256编码中的阿拉伯字符。

无论我尝试什么,我总是最终只有一堆???每当我将阿拉伯语字符串传递给图书馆时。

我的方法是将utf-8编码的字符串转换为C#代码中的iso-1256,并将结果传递给C ++库。

C#中的转换如下所示:

var bytes = encUtf8.GetBytes((string)value);                   
String value1256 = enc1256.GetString(Encoding.Convert(encUtf8, enc1256, bytes));

然后我继续将value1256传递给库。

调用的CLI函数将接受String ^ sVal参数。 遗留代码在内部使用CString,所以我必须转换字符串,这就是我的问题。 无论我如何转换字符串,我最终都只是???。

以下是我到目前为止尝试过的转化列表,所有转化都会产生相同的输出。当我检查调试器时,原始sVal正确显示为阿拉伯字符,但下面列出的每个转换只会导致???:

pin_ptr<const wchar_t> wch = PtrToStringChars(sVal);
            CString cstring6(wch);
            wchar_t* A= ( wchar_t* )( Marshal::StringToHGlobalAnsi(sVal).ToPointer() );

            std::string stdString = marshal_as<std::string>(sVal); 
            CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> cStringT = CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>( sVal );
            CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> cStringT2 = CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>( A );
            CString cString1 = CString( sVal );
            CString cString2 = CString(stdString.c_str());
            CString cString3 = stdString.c_str();
            CString cString4 = CString( _T( stdString.c_str() ));
            CString cString5 = CString( sVal );

            marshal_context^ context = gcnew marshal_context();
            const char* c_s = context->marshal_as<const char*>(sVal);

显然我在这里做错了什么。 请你这么好,并指出我在这里正确的方向。

1 个答案:

答案 0 :(得分:2)

如果你有String^个对象,那么它只有一种可能的编码:UTF-16。为了明确地传递不同的编码,它需要是一个字节数组,而不是一个字符串。

enc1256.GetString(Encoding.Convert(encUtf8, enc1256, bytes));

你接近这条线,但并不完全。您正在使用UTF-8编码的bytes并将它们转换为1256编码的字节数组(好),然后将其转换回UTF-16 String^(错误)。 (如果您查看value1256和原始的value,它们可能完全相同。)之后,当您将所有转换转换为各种字符串时,它们就是&#39 ;所有人都在进行UTF-16的全新转换,他们可能都转换为ASCII或默认的1252代码页。

我要做的是调用Encoding::GetBytes(String^),然后将该字节数组传递给非托管C ++库。 (绕过UTF-8是不必要的。)一旦你切换到那个编码,试着把它想象成一个字节数组,而不是一个字符串。 (我不愿意使用任何字符串类,无论是托管还是非托管。)

您可以在C#或C ++ / CLI中调用GetBytes,但我会使用C ++ / CLI:让C#看到的界面清洁&amp;使用C#String^类型,而不是要求调用者知道正确的编码方式。