《libiconv字符集轉換庫使用方法》一文中說到了libiconv可以實現不同字符集的轉換。比如GBK轉BIG5等。在項目中因為需要,找到這個庫。可是這個庫在C#中沒有很好的支持。不過,想著既然是C++的庫,那只要動態加載DLL的接口就好了。可是調用並不順利,傳進去的IntPtr或者byte數組總是拿不到數據。後面回到了C++的方式去調用,幾經調試,總算找到了原因。
是iconv接口在轉換完成後,指針的位置往後移了。而在C#中調用DLL後回來的指針,已經是移動後的,所以拿不到所要的數據。
經過多種嘗試,沒有辦法將指針移回到原位。
後來,通過C++的二次封裝,在C++中將指針的位置移到了原來的位置,再用C#來調用,總算達到了目的。
#include//包函 libiconv庫頭文件 #include "iconv.h" //導入 libiconv庫 #pragma comment(lib,"libiconv.lib") using namespace std; #define DLL_EXPORT extern "C" __declspec(dllexport) DLL_EXPORT int ChangeCode( const char* pFromCode, const char* pToCode, const char* pInBuf, size_t* iInLen, char* pOutBuf, size_t* iOutLen ) { size_t outLenTemp=*iOutLen; iconv_t hIconv = iconv_open( pToCode, pFromCode ); if ( -1 == (int)hIconv ) { return -100;//打開失敗,可能不支持的字符集 } //開始轉換 int iRet = iconv( hIconv, (const char**)(&pInBuf), iInLen, (char**)(&pOutBuf), iOutLen ); if (iRet>=0) { pOutBuf=pOutBuf-(outLenTemp-*iOutLen);//轉換後pOutBuf的指針被移動,必須移回到起始位置 } else { iRet=-200; } //關閉字符集轉換 iconv_close( hIconv ); return iRet; }
C#調用的部分
////// 字符器轉換. /// 每次轉換都需要打開轉換器、字符集轉換、關閉轉換器。 /// /// 源字符集編碼 /// 目標字符集編碼 /// 待轉換的內容 /// 待轉換的長度。轉換成功後,將變成0. /// 轉換後的內容 /// 轉換長度。轉換成功後,將變成原值減去轉換後的內容所占空間的長度 ///[DllImport("CharsetConvert.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int ChangeCode(string pFromCode, string pToCode, byte[] pInBuf, ref int iInLen, byte[] pOutBuf, ref int iOutLen);
private void buttonOneConvert_Click(object sender, EventArgs e) { string toCode = "BIG5"; string fromCode = "GBK"; string inStr = "國k"; byte[] inBuf = Encoding.Default.GetBytes(inStr); byte[] outBuf = new byte[100]; int inLen = inBuf.Length; int outLen = outBuf.Length; int result = CharsetConvter.ChangeCode(fromCode, toCode, inBuf, ref inLen, outBuf, ref outLen); if (result < 0) { MessageBox.Show("轉換失敗"); } else { String outStr = Encoding.GetEncoding("BIG5").GetString(outBuf); MessageBox.Show(outStr); } }