一、解压文件

二、新建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;
}



3768

被折叠的 条评论
为什么被折叠?



