通过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);

显然我在这里做错了什么。请给我指一下正确的方向。

通过CLI通过1256编码将字符串从c#传递到本地c++库

如果你有一个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^类型,而不是要求调用者知道如何正确编码。