libiconv字符集转换库在C#中的使用


《libiconv字符集转换库使用方法》一文中说到了libiconv可以实现不同字符集的转换。比如GBK转BIG5等。在项目中因为需要,找到这个库。可是这个库在C#中没有很好的支持。不过,想着既然是C++的库,那只要动态加载DLL的接口就好了。可是调用并不顺利,传进去的IntPtr或者byte数组总是拿不到数据。后面回到了C++的方式去调用,几经调试,总算找到了原因。

是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);
            }

        }

C#多线程编程实例 线程与窗体交互【附源码】

C#数学运算表达式解释器

在C语言中解析JSON配置文件

C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码

本文永久更新链接地址:

相关内容