libiconv Qt中的各种字符编码转化

来源:互联网 发布:java项目部署到tomcat 编辑:程序博客网 时间:2024/06/06 00:59

首先声明一下:可以用一个跨平台的库,网址:http://www.gnu.org/software/libiconv/  Qt中正是引用了这个库

以下是我在WIN32下面编译成功的工程 : http://download.csdn.net/download/ljt350740378/9943280

下载了源码后,先是编译此库:https://www.codeproject.com/Articles/302012/How-to-Build-libiconv-with-Microsoft-Visual-Studio  -- 这个是编译此库的说明文档

下面是说明:

How to Get the Source Code of libiconv

At the moment, the most recent version of libiconv is 1.14. You can download the source code of libiconv1.14 here and here. Of course, you can get the older versions of libiconv here.

How to Build

I am going to explain the case of Microsoft Visual Studio 2010 professional edition but the explanation can be applied to the earlier versions of Microsoft Visual Studio and to the express edition of each of them.

First Step

You download the most recent version of libiconv which is 1.14 from here or here. And unzip the downloaded file "libiconv-1.14.tar.gz" on your certain folder.

Second Step

You run your Microsoft Visual Studio. Then, you make a new WIN32 project. Let's say "libiconv" as the project name. Check to create directory for solution. Choose DLL as the application type and check Empty project for additional options. Click the button "finish" to generate the new project.

Third Step

Now, you have to copy some files from the folders generated by unzipping "libiconv-1.14.tar.gz" to the project folders. To build "libiconv", you need to compile three files "localcharset.c", "relocatable.c" and "iconv.c". That is the key idea!

Copy three files "relocatable.h", "relocatable.c" and "iconv.c" in the folder "...\libiconv-1.14\lib\" to the project folder "...\libiconv\libiconv\".
Copy "...\libiconv-1.14\libcharset\lib\localcharset.c" to the project folder "...\libiconv\libiconv\".
Copy "...\libiconv-1.14\libcharset\include\localcharset.h.build.in" to the project folder "...\libiconv\libiconv\" and then, rename the copied "localcharset.h.build.in" to "localcharset.h.
Copy "...\libiconv-1.14\windows\libiconv.rc" to the project folder "...\libiconv\libiconv\".

Make folder "include" under the project folder "...\libiconv\" so to make "...\libiconv\include". 
Copy "...\libiconv-1.14\include\iconv.h.build.in" to the project include folder "...\libiconv\include" and then, rename the copied "iconv.h.build.in" to "iconv.h".
Copy "...\libiconv-1.14\config.h.in" to the project include folder "...\libiconv\include" and then, rename the copied "config.h.in" to "config.h".
And then, copy all the header files (*.h) and definition files (*.def) in the folder "...\libiconv-1.14\lib" to the project include folder "...\libiconv\include".

Fourth Step

Now, you have to add existing items to the project "libiconv" that we made at the second step. Execute "project > Add Existing items..." at the main menu to add existing items to the project.

Fifth Step

You can make 64-bit platform through configuration manager in order to generate libiconv.dll for 64-bit system. You can also make two other configurations "ReleaseStatic" and "DebugStatic" in order to generatelibiconvStatic.lib as a static link library.

At the project properties, change Output Directory as "$(SolutionDir)$(Configuration)_$(Platform)\" and Intermediate Directory as "$(SolutionDir)obj\$(ProjectName)\$(Configuration)_$(Platform)\".

Change Include Directories as "..\include;$(IncludePath)":

You have to add "BUILDING_LIBICONV" and "BUILDING_LIBCHARSET" to Peprocessor Definitions of all Platforms and of all configurations.

You'd better set Runtime Library to "Multi-threaded" when building dynamic link library libiconv.dll. Then, the dependency on VC Runtime library can be controlled by the applications that will be built and dynamically linked with libiconv.dll because libiconv.dll does not need VC Runtime library but only the application that useslibiconv.dll may or may not need VC Runtime library. However, when building the static link librarylibiconvStatic.lib, you can choose Runtime Library option for libiconvStatic.lib depending on the application that uses libiconvStatic.lib.

You have to change Precompiled Header option to "Not Using Precompiled Headers".

Sixth Step

Now, it is the time to tweak the source code of the libiconv.

libiconv.rc

Open libiconv.rc with text editor or the source code editor of Visual Studio IDE by double-clicking libiconv.rc in the Solution explorer and insert some code at line 4 as follows:

///////////////////////// 추가 / ADD / ДОВАВЛЯТЬ //////////////////////#define PACKAGE_VERSION_MAJOR       1#define PACKAGE_VERSION_MINOR       14#define PACKAGE_VERSION_SUBMINOR    0#define PACKAGE_VERSION_STRING      "1.14"////////////////////////////////////////////////////////////////////////////////

You may be asked to change Line endings to "Windows (CR LF)". Then, let it do so. It will be more convenient for you if you mainly use Windows.

localcharset.c

Open localcharset.c and delete or comment the lines 76 - 79 as follows:

///////////////////////// 삭제 / DELETE / удалить //////////////////////////* Get LIBDIR.  *///#ifndef LIBDIR//# include "configmake.h"//#endif////////////////////////////////////////////////////////////////////////////////

iconv.c

Open iconv.c and delete or comment the lines 246 - 248 and add three lines there as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ /////////////////////////size_t iconv (iconv_t icd,//              ICONV_CONST char* * inbuf, size_t *inbytesleft,//              char* * outbuf, size_t *outbytesleft)///////////////////////// ?? / ADD / ????????? //////////////////////size_t iconv (iconv_t icd,              const char* * inbuf, size_t *inbytesleft,              char* * outbuf, size_t *outbytesleft)////////////////////////////////////////////////////////////////////////////////

localcharset.h

Open localcharset.h and delete or comment the lines 23 - 27 and add 7 lines there as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ /////////////////////////#if @HAVE_VISIBILITY@ && BUILDING_LIBCHARSET//#define LIBCHARSET_DLL_EXPORTED __attribute__((__visibility__("default")))//#else//#define LIBCHARSET_DLL_EXPORTED//#endif///////////////////////// ?? / ADD / ????????? //////////////////////#ifdef BUILDING_LIBCHARSET#define LIBCHARSET_DLL_EXPORTED __declspec(dllexport)#elif USING_STATIC_LIBICONV#define LIBCHARSET_DLL_EXPORTED#else#define LIBCHARSET_DLL_EXPORTED __declspec(dllimport)#endif////////////////////////////////////////////////////////////////////////////////

config.h

Open config.h in the project include folder "...\libiconv\include" and delete or comment the lines 29 - 30 as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ //////////////////////////* Define as good substitute value for EILSEQ. *///#undef EILSEQ////////////////////////////////////////////////////////////////////////////////

Otherwise you can redefine EILSEQ as good substitute value.

iconv.h

Open iconv.h in the project include folder "...\libiconv\include" and delete or comment the line 175 and add 1 line as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ /////////////////////////#if @HAVE_WCHAR_T@///////////////////////// 추가 / ADD / ДОВАВЛЯТЬ //////////////////////#if HAVE_WCHAR_T////////////////////////////////////////////////////////////////////////////////

Delete or comment the line 128 and add 1 line as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ /////////////////////////#if @USE_MBSTATE_T@///////////////////////// 추가 / ADD / ДОВАВЛЯТЬ //////////////////////#if USE_MBSTATE_T////////////////////////////////////////////////////////////////////////////////

Delete or comment the lines 107-108 and add 2 lines as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ /////////////////////////#if @USE_MBSTATE_T@//#if @BROKEN_WCHAR_H@///////////////////////// 추가 / ADD / ДОВАВЛЯТЬ //////////////////////#if USE_MBSTATE_T#if BROKEN_WCHAR_H////////////////////////////////////////////////////////////////////////////////

Delete or comment the line 89 and add 2 lines as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ /////////////////////////extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, @ICONV_CONST@ char* * inbuf, //size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);///////////////////////// 추가 / ADD / ДОВАВЛЯТЬ //////////////////////extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);////////////////////////////////////////////////////////////////////////////////

Delete or comment the lines 26 - 31 and add 8 lines as follows:

///////////////////////// 삭제 / DELETE / УДАЛИТЬ /////////////////////////#if @HAVE_VISIBILITY@ && BUILDING_LIBICONV//#define LIBICONV_DLL_EXPORTED __attribute__((__visibility__("default")))//#else//#define LIBICONV_DLL_EXPORTED//#endif//extern LIBICONV_DLL_EXPORTED @DLL_VARIABLE@ int _libiconv_version; /* Likewise *////////////////////////// 추가 / ADD / ДОВАВЛЯТЬ //////////////////////#if BUILDING_LIBICONV#define LIBICONV_DLL_EXPORTED __declspec(dllexport)#elif USING_STATIC_LIBICONV#define LIBICONV_DLL_EXPORTED#else#define LIBICONV_DLL_EXPORTED __declspec(dllimport)#endifextern LIBICONV_DLL_EXPORTED int _libiconv_version; /* Likewise */////////////////////////////////////////////////////////////////////////////////

How to Use

When you use newly built libiconv, the only header file that you need is iconv.h. You will need to link either the import library libiconv.lib or the static library libiconvStatic.lib in your project property or write the code in one of your source file as follows:

#pragma comment (lib, "libiconv.lib")or#pragma comment (lib, "libiconvStatic.lib")

In the source of the application that uses this library either libiconv.dll or libiconvStatic.lib, if you don't define anything but only include iconv.h, your application will use libiconv.dll while it will use libiconvStatic.lib if you define USING_STATIC_LIBICONV before you include iconv.h in your application as follows:

//#define USING_STATIC_LIBICONV#include <iconv.h>

Copyright Issues

The original libiconv is under LGPL licence. So, the tweaked libiconv has also to be under LGPL. If you develop any application that uses libiconv, you have to be careful about copyright issues. If your application is linked with libiconv.dll dynamically, you don't have to publicize your source code of your application. However, if your application is linked statically with libiconvStatic.lib, you have to publicize either the source code of the application or the object files (*.obj) of the application so that others can build the application that is linked statically with the library under LGPL license.

下面是编译后好


iconv.h

C:\Qt\Qt5.7.1\5.7\Src\qtwebengine\src\3rdparty\chromium\third_party\talloc\libreplace\system

感谢:http://blog.csdn.net/denny97104/article/details/45443055


QtConsole.pro中的代码:---WINDOWS下:

QT += core widgetsQT -= guiCONFIG += c++11TARGET = QtConsoleCONFIG += consoleCONFIG -= app_bundleTEMPLATE = appSOURCES += main.cpp# The following define makes your compiler emit warnings if you use# any feature of Qt which as been marked deprecated (the exact warnings# depend on your compiler). Please consult the documentation of the# deprecated API in order to know how to port your code away from it.DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.# In order to do so, uncomment the following line.# You can also select to disable deprecated APIs only up to a certain version of Qt.#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0LIBS += C:/Qt/Qt5.7.1/Tools/mingw530_32/i686-w64-mingw32/lib/libiconv.a#LIBS += c:/MinGW/msys/1.0/local/lib/libzbar.a#LIBS += c:/MinGW/lib/libiconv.a
main.cpp:--备注:在此中有WINDOWS中的函数,但是并没有使用,只是留着查阅

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。//#include<map>#include<string>#include<iostream>#include <vector>#include <stdlib.h>#include <algorithm>using namespace std;#include <string.h>#include <stdio.h>#include <map>#include <hash_map>using namespace std;#include <QCoreApplication>#include <QDebug>#include <QMessageBox>#define _CUR_SYS_LINUX_ 1//根据你的系统自己设置_CUR_SYS_LINUX_#ifdef _CUR_SYS_LINUX_    #include <iconv.h>#else    #include <windows.h>    #include <stdio.h>#endif/*unicode文件:0xff 0xfe + 内容utf8文件:0xEF 0xBB 0xBF + 内容无bom的utf8文件:没有前面3个字节"回车"(carriage return) 13"换行"(line feed)       10Windows系统里面,每行结尾是"<回车><换行>",即"\r\n";Unix系统里,每行结尾只有"<换行>",即"\n";Mac系统里,每行结尾是"<回车>",即"\r"。*/#ifdef _CUR_SYS_LINUX_inline int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen){    iconv_t cd;    //int rc;    char **pin = &inbuf;    char **pout = &outbuf;    cd = iconv_open(to_charset,from_charset);    if (cd==0) return -1;    memset(outbuf,0,outlen);    //if (iconv(cd,pin,(size_t*)(&inlen),pout,(size_t*)(&outlen))==-1) return -1;    iconv(cd,pin,(size_t*)(&inlen),pout,(size_t*)(&outlen));    iconv_close(cd);    return 0;}#endif/*****************************************************utf8到ansi的转换*输入参数:*输出参数:*****************************************************/inline QByteArray Utf8ToAnsi(QByteArray &inUtf8){#ifdef _CUR_SYS_LINUX_    QByteArray qbaOut;    char *outBuf = new char[inUtf8.size()+1];    memset(outBuf,0,inUtf8.size()+1);    char utf8Buf[] = {"utf-8"};    char gb2312Buf[] = {"gb2312"};    //ansi.resize(utf8.size());    int code = code_convert(utf8Buf,gb2312Buf,inUtf8.data(),inUtf8.size(),outBuf,inUtf8.size());    if (code == -1) {        delete []outBuf;        qbaOut = "";        //qDebug() << "Utf8ToAnsi error";        return qbaOut;    }    qbaOut = outBuf;    ////qDebug() << "utf8 length=" << utf8.size();    ////qDebug() << "ansi length=" << ansi.size();    delete []outBuf;    return qbaOut;#else    int len;    QByteArray result;    //UTF-8转UNICODE    len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8.data(), -1, NULL,0);    WCHAR * unicode = new WCHAR[len+1];    memset(unicode, 0, len * 2 + 2);    MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8.data(), -1, unicode, len);    //UNICODE转ANSI    len = WideCharToMultiByte(CP_ACP, 0, unicode, -1, NULL, 0, NULL, NULL);    char *ansi=new char[len + 1];    memset(ansi, 0, len + 1);    WideCharToMultiByte (CP_ACP, 0, unicode, -1, ansi, len, NULL,NULL);    //赋值    result = ansi;    delete[] unicode;    delete[] ansi;    return result;#endif}/*****************************************************ansi到utf8的转换*输入参数:*输出参数:*****************************************************/inline QByteArray AnsiToUtf8(QByteArray &ansi){#ifdef _CUR_SYS_LINUX_    QByteArray utf8;    char *buf = new char[ansi.size()*2];    char utf8Buf[] = {"utf-8"};    char gb2312Buf[] = {"gb2312"};    //ansi.resize(ansi.size()*2);    int code = code_convert(gb2312Buf,utf8Buf,ansi.data(),ansi.size(),buf,2*ansi.size());    if (code == -1) {        delete []buf;        utf8 = "";        return utf8;    }    utf8 = buf;    delete []buf;    return utf8;#else    int len;    QByteArray result;    //ANSI转UNICODE    len = MultiByteToWideChar(CP_ACP, NULL, ansi.data(), -1, NULL, 0);    WCHAR * unicode = new WCHAR[len+1];    memset(unicode, 0, len * 2 + 2);    MultiByteToWideChar(CP_ACP, NULL, ansi.data(), -1, unicode, len);    //UNICODE转utf8    len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);    char *utf8=new char[len + 1];    memset(utf8, 0, len + 1);    WideCharToMultiByte (CP_UTF8, 0, unicode, -1, utf8, len, NULL,NULL);    //赋值    result = utf8;    delete[] unicode;    delete[] utf8;    return result;#endif}int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    QByteArray oldUtf8 = "ansi_str ansi字符串";    qDebug()<<"ba.size()="<<oldUtf8.size();    QByteArray retAnsi = Utf8ToAnsi(oldUtf8);    qDebug()<<"retBa.size()="<<retAnsi.size();    QByteArray retUtf8 = AnsiToUtf8(retAnsi);    if(oldUtf8==retUtf8)        qDebug()<<"result="<<(oldUtf8==retUtf8);    //map<char*, char*> mapx = GetDictionary(NULL);    return a.exec();}

下面是在linux下面的使用:


在LINUX下面使用,首先要安装

libiconv包和gettext包:
下面是编译安装gettext库--libiconv一样的方法
$tar zxvf gettext-0.11.2.tar.gz
$cd gettext-0.11.2
$ ./configure --prefix=/usr/local
$ make
$ make install
在/usr/local/lib/目录下,拷备需要的库文件libcharset.so.1, libiconv.so.2。
在PRO里面:
LIBS +=  /usr/local/lib/libiconv.so
代码如下:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。//#include<map>#include<string>#include<iostream>#include <vector>#include <stdlib.h>#include <algorithm>using namespace std;#include <string.h>#include <stdio.h>#include <map>#include <hash_map>using namespace std;#include <QCoreApplication>#include <QDebug>#include <QMessageBox>#define _CUR_SYS_LINUX_ 1//根据你的系统自己设置_CUR_SYS_LINUX_#ifdef _CUR_SYS_LINUX_    #include <iconv.h>#else    #include <windows.h>    #include <stdio.h>#endif/*unicode文件:0xff 0xfe + 内容utf8文件:0xEF 0xBB 0xBF + 内容无bom的utf8文件:没有前面3个字节"回车"(carriage return) 13"换行"(line feed)       10Windows系统里面,每行结尾是"<回车><换行>",即"\r\n";Unix系统里,每行结尾只有"<换行>",即"\n";Mac系统里,每行结尾是"<回车>",即"\r"。*/#ifdef _CUR_SYS_LINUX_inline int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen){    iconv_t cd;    //int rc;    char **pin = &inbuf;    char **pout = &outbuf;    cd = iconv_open(to_charset,from_charset);    if (cd==0) return -1;    memset(outbuf,0,outlen);    //if (iconv(cd,pin,(size_t*)(&inlen),pout,(size_t*)(&outlen))==-1) return -1;    iconv(cd,pin,(size_t*)(&inlen),pout,(size_t*)(&outlen));    iconv_close(cd);    return 0;}#endif/*****************************************************utf8到ansi的转换*输入参数:*输出参数:*****************************************************/QByteArray Utf8ToAnsi(QByteArray &inUtf8){#ifdef _CUR_SYS_LINUX_    QByteArray qbaOut;    //char *outBuf = new char[inUtf8.size()+1];    char *outBuf = new char[inUtf8.size()*4];    char *oldOutBuf=outBuf;;    //memset(outBuf,0,inUtf8.size()+1);    char utf8Buf[] = {"utf-8"};    char gb2312Buf[] = {"gb2312"};    //ansi.resize(utf8.size());    //int code = code_convert(utf8Buf,gb2312Buf,inUtf8.data(),inUtf8.size(),outBuf,inUtf8.size());    int code = code_convert(utf8Buf,gb2312Buf,inUtf8.data(),inUtf8.size(),outBuf,inUtf8.size()*4);    if (code == -1) {        delete []outBuf;        qbaOut = "";        //qDebug() << "Utf8ToAnsi error";        return qbaOut;    }    qbaOut = outBuf;    ////qDebug() << "utf8 length=" << utf8.size();    ////qDebug() << "ansi length=" << ansi.size();//    delete []outBuf;    delete []oldOutBuf;    return qbaOut;#else    int len;    QByteArray result;    //UTF-8转UNICODE    len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8.data(), -1, NULL,0);    WCHAR * unicode = new WCHAR[len+1];    memset(unicode, 0, len * 2 + 2);    MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8.data(), -1, unicode, len);    //UNICODE转ANSI    len = WideCharToMultiByte(CP_ACP, 0, unicode, -1, NULL, 0, NULL, NULL);    char *ansi=new char[len + 1];    memset(ansi, 0, len + 1);    WideCharToMultiByte (CP_ACP, 0, unicode, -1, ansi, len, NULL,NULL);    //赋值    result = ansi;    delete[] unicode;    delete[] ansi;    return result;#endif}/*****************************************************ansi到utf8的转换*输入参数:*输出参数:*****************************************************/QByteArray AnsiToUtf8(QByteArray &ansi){#ifdef _CUR_SYS_LINUX_    QByteArray utf8;    char *buf = new char[ansi.size()*4];    char *oldbuf = buf;    char utf8Buf[] = {"utf-8"};    char gb2312Buf[] = {"gb2312"};    //ansi.resize(ansi.size()*2);    int code = code_convert(gb2312Buf,utf8Buf,ansi.data(),ansi.size(),buf,4*ansi.size());    if (code == -1) {        delete []buf;        utf8 = "";        return utf8;    }    utf8 = buf;    //delete []buf;    delete []oldbuf;    return utf8;#else    int len;    QByteArray result;    //ANSI转UNICODE    len = MultiByteToWideChar(CP_ACP, NULL, ansi.data(), -1, NULL, 0);    WCHAR * unicode = new WCHAR[len+1];    memset(unicode, 0, len * 2 + 2);    MultiByteToWideChar(CP_ACP, NULL, ansi.data(), -1, unicode, len);    //UNICODE转utf8    len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);    char *utf8=new char[len + 1];    memset(utf8, 0, len + 1);    WideCharToMultiByte (CP_UTF8, 0, unicode, -1, utf8, len, NULL,NULL);    //赋值    result = utf8;    delete[] unicode;    delete[] utf8;    return result;#endif}int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    QByteArray oldUtf8 = "ansi_str ansi字符串";    qDebug()<<"ba.size()="<<oldUtf8.size();    QByteArray retAnsi = Utf8ToAnsi(oldUtf8);    qDebug()<<"retBa.size()="<<retAnsi.size();    QByteArray retUtf8 = AnsiToUtf8(retAnsi);    if(oldUtf8==retUtf8)        qDebug()<<"result="<<(oldUtf8==retUtf8);    //map<char*, char*> mapx = GetDictionary(NULL);    return a.exec();}



原创粉丝点击