通过CLI通过1256编码将字符串从c#传递到本地c++库
本文关键字:通过 c++ 1256 CLI 编码 字符串 | 更新日期: 2023-09-27 18:17:11
我必须在c#项目中使用旧的c++库。. Net Framework 4 .
一般来说,我已经设置好并运行了一切,但将字符串值传递给库会给我带来问题。
我收到utf-8格式的字符串值,其中包含阿拉伯字符。库正在处理iso-1256编码的阿拉伯字符。
不管我怎么努力,我总是以一堆??当我将阿拉伯语字符串传递给库时。
我的方法是在c#代码中将utf-8编码的字符串转换为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);
显然我在这里做错了什么。请给我指一下正确的方向。
如果你有一个String^
对象,它只有一种可能的编码:UTF-16。为了显式地传递不同的编码,它需要是字节数组,而不是字符串。
enc1256.GetString(Encoding.Convert(encUtf8, enc1256, bytes));
你很接近这条线,但不完全是。您正在使用UTF-8编码的bytes
并将它们转换为1256编码的字节数组(好),但随后将其转换回UTF-16 String^
(坏)。(如果你看看value1256
和你原来的value
,它们可能完全一样。)之后,当你做所有这些转换到各种字符串时,它们都在做从UTF-16的新的转换,它们可能都在转换到ASCII或默认的1252代码页。
我要做的是调用Encoding::GetBytes(String^)
,然后将字节数组传递给您的非托管c++库。(没有必要绕过UTF-8。)一旦切换到这种编码方式,请尝试将其视为字节数组,而不是字符串。(我会避免使用任何字符串类,无论是托管的还是非托管的。)
你可以在c#或c++/CLI中调用GetBytes
,但我会用c++/CLI:让c#看到的接口干净&使用c# String^
类型,而不是要求调用者知道如何正确编码。