Windows下编译iconv

下载地址
在这里插入图片描述
点击对应连接即可下载
所有版本列表

一、解压文件

在这里插入图片描述

二、新建vs空项目,拷贝源文件到项目下(静态库)

1、拷贝,修改文件名

config.h.in             ->      config.h
include/iconv.h.in      ->      iconv.h
lib/iconv.c             ->      iconv.c

// localcharset
libcharset/include/localcharset.h.in    ->  localcharset.h
libcharset/lib/localcharset.c           ->  localcharset.c

2、修改文件

iconv.h
1、去掉所有@符号
2、注释掉 @ICONV_CONST@  (82)
extern size_t iconv (iconv_t cd, /*@ICONV_CONST@*/ char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft);
iconv.c
注释掉 @ICONV_CONST@  (263)
size_t iconv (iconv_t icd,
              /*ICONV_CONST*/ char** inbuf, size_t* inbytesleft,
              char* * outbuf, size_t *outbytesleft)
loop_unicode.h
增加宏定义 (Windows kits里有该定义)
#define EILSEQ          42 

在这里插入图片描述

三、编译

增加预处理器

_CRT_SECURE_NO_WARNINGS

增加包含目录(当前目录和iconv原目录)

C:\Users\work\Downloads\libiconv-1.18\lib
.

编译通过后,会出现iconv.lib
在这里插入图片描述

四、封装以及使用

iconvWrapper.h

#pragma once
#include <iconv.h>
#include <string>
#include <vector>
#include <stdexcept>


#pragma comment(lib, "../iconv/iconv.lib")
namespace iconv_wrap
{
    class conv_t
    {
    public:
        conv_t(const char* to, const char* from)
            : cd(::iconv_open(to, from))
        {
            if (cd == reinterpret_cast<iconv_t>(-1))
                throw std::runtime_error("iconv_open failed");
        }
        ~conv_t() { ::iconv_close(cd); }
        conv_t(const conv_t&) = delete;
        conv_t& operator=(const conv_t&) = delete;


        std::string convert(const char* inbuf, size_t inbytes)
        {
            std::string out;
            size_t    inleft = inbytes;
            size_t    outleft = 0;
            const char* inptr = inbuf;

            // capacity size
            size_t guess = inbytes * 4 + 4;
            out.resize(guess);
            char* outptr = &out[0];

            while (inleft > 0)
            {
                outleft = out.size() - (outptr - &out[0]);
                size_t rc = ::iconv(cd,
                    const_cast<char**>(&inptr), &inleft,
                    &outptr, &outleft);
                if (rc == static_cast<size_t>(-1))
                {
                    if (errno == E2BIG)   // flush not enough
                    {
                        size_t used = outptr - &out[0];
                        out.resize(out.size() * 2);
                        outptr = &out[0] + used;
                        outleft = out.size() - used;
                    }
                    else
                        throw std::runtime_error("iconv failed");
                }
            }
            // iconv may contans shift state, do refresh
            ::iconv(cd, nullptr, nullptr, &outptr, &outleft);
            out.resize(outptr - &out[0]);
            return out;
        }

    private:
        iconv_t cd;
    };

    // 1. UTF-8 ↔ ANSI
    inline std::string utf8_to_ansi(const std::string& u8, const char* ansi_cp = "")
    {
        // ansi_cp = ""  indicates locale 
        conv_t conv(ansi_cp[0] ? ansi_cp : "", "UTF-8");
        return conv.convert(u8.data(), u8.size());
    }
    inline std::string ansi_to_utf8(const std::string& ansi, const char* ansi_cp = "")
    {
        conv_t conv("UTF-8", ansi_cp[0] ? ansi_cp : "");
        return conv.convert(ansi.data(), ansi.size());
    }

    // 2. UTF-8 ↔ std::wstring
    inline std::wstring utf8_to_wstring(const std::string& u8)
    {
#ifdef _WIN32
        const char* wchar_enc = "UTF-16LE";
#else
        const char* wchar_enc = "UTF-32LE";
#endif
        conv_t conv(wchar_enc, "UTF-8");
        std::string raw = conv.convert(u8.data(), u8.size());
        const wchar_t* p = reinterpret_cast<const wchar_t*>(raw.data());
        return std::wstring(p, p + raw.size() / sizeof(wchar_t));
    }

    inline std::string wstring_to_utf8(const std::wstring& ws)
    {
#ifdef _WIN32
        const char* wchar_enc = "UTF-16LE";
#else
        const char* wchar_enc = "UTF-32LE";
#endif
        const char* inptr = reinterpret_cast<const char*>(ws.data());
        size_t      inbytes = ws.size() * sizeof(wchar_t);
        conv_t conv("UTF-8", wchar_enc);
        return conv.convert(inptr, inbytes);
    }

    // 3. ANSI ↔ std::wstring
    inline std::wstring ansi_to_wstring(const std::string& ansi, const char* ansi_cp = "")
    {
#ifdef _WIN32
        const char* wchar_enc = "UTF-16LE";
#else
        const char* wchar_enc = "UTF-32LE";
#endif
        conv_t conv(wchar_enc, ansi_cp[0] ? ansi_cp : "");
        std::string raw = conv.convert(ansi.data(), ansi.size());
        const wchar_t* p = reinterpret_cast<const wchar_t*>(raw.data());
        return std::wstring(p, p + raw.size() / sizeof(wchar_t));
    }

    inline std::string wstring_to_ansi(const std::wstring& ws, const char* ansi_cp = "")
    {
#ifdef _WIN32
        const char* wchar_enc = "UTF-16LE";
#else
        const char* wchar_enc = "UTF-32LE";
#endif
        const char* inptr = reinterpret_cast<const char*>(ws.data());
        size_t      inbytes = ws.size() * sizeof(wchar_t);
        conv_t conv(ansi_cp[0] ? ansi_cp : "", wchar_enc);
        return conv.convert(inptr, inbytes);
    }
}

main.cpp

#include <iostream>
#include "iconvWrapper.h"

int main()
{
    std::wstring wstrData(L"你好,测试");
    std::string strResult = iconv_wrap::wstring_to_utf8(wstrData);
    std::cout << strResult << "\n";

    std::string strGbk = iconv_wrap::utf8_to_ansi(strResult);
    std::cout << "Gbk: " << strGbk << "\n";

    getchar();


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值