是iconv接口在转换完成后,指针的位置往后移了。而在C#中调用DLL后回来的指针,已经是移动后的,所以拿不到所要的数据。
经过多种尝试,没有办法将指针移回到原位。
后来,通过C++的二次封装,在C++中将指针的位置移到了原来的位置,再用C#来调用,总算达到了目的。
#include <fstream> //包函 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#调用的部分
/// <summary> /// 字符器转换. /// 每次转换都需要打开转换器、字符集转换、关闭转换器。 /// </summary> /// <param name="pFromCode">源字符集编码</param> /// <param name="pToCode">目标字符集编码</param> /// <param name="pInBuf">待转换的内容</param> /// <param name="iInLen">待转换的长度。转换成功后,将变成0.</param> /// <param name="pOutBuf">转换后的内容</param> /// <param name="iOutLen">转换长度。转换成功后,将变成原值减去转换后的内容所占空间的长度</param> /// <returns></returns> [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); } }