mlang.dllのConvertINetString関数を使った文字コードの変換

mlang.dllのConvertINetString関数を使った文字コードを変換するサンプル

C++ Builder 2009を使いました。
_TCHARのマップ先は「wchar_t」に設定しています。

本題に入る前に前準備として、DLLのリソース管理クラス(RAII)を用意します。
このクラスTDllはデストラクタでFreeLibraryを行うので、DLLのハンドルの解放のし忘れを防ぐことができます。

/**
 * DLLのリソース管理(RAII)
 */
class TDll
{
public:
  TDll(const UnicodeString& DllName)
  {
    FDll = LoadLibrary(DllName.c_str());
  }
  ~TDll()
  {
    if (!FDll) FreeLibrary(FDll);
  }
  operator bool() const
  {
    return FDll;
  }
  operator HMODULE() const
  {
    return FDll;
  }
private:
  HMODULE FDll;
};

ConvertINetStringのtypedefを定義します。
なくてもいいのですが、あるとソースコートが読みやすくなります。

typedef HRESULT WINAPI (*TConvertINetString)(LPDWORD lpdwMode, DWORD dwSrcEncoding, DWORD dwDstEncoding, LPCSTR lpSrcStr, LPINT lpnSrcSize, LPBYTE lpDstStr, LPINT lpnDstSize);

mlang.dllを読み込みます。
読み込みに失敗したときはエラーメッセージを表示します。

TDll dll("mlang.dll");
if (!dll)
{
  std::puts("DLLの読み込みに失敗しました。");
  return 0;
}

ConvertINetString関数のアドレスを取得します。
失敗したときはエラーメッセージを表示します。

//関数のアドレスの取得
FARPROC proc = GetProcAddress(dll, "ConvertINetString");
if (!proc)
{
  std::puts("関数のアドレスの取得に失敗しました。");
  return 0;
}
TConvertINetString ConvertINetString = reinterpret_cast<TConvertINetString>(proc);

ConvertINetString関数に渡す変数を用意します。
今回のサンプルではShift_JISをEUC-JPに変換します。

DWORD mode = 0;
AnsiStringT<932> sjis = "あいうえおかきくけこさしすせそたちつてと";
int sjisLen = sjis.Length();
int eucLen = sjisLen * 2 + 1;
boost::scoped_array<char> euc(new char[eucLen]);
ZeroMemory(euc.get(), eucLen);

ConvertINetString関数を呼び出して変換します。
変換に失敗したときはエラーメッセージを表示します。

//変換
HRESULT result = ConvertINetString(&mode, 932, 51932, sjis.c_str(), &sjisLen, euc.get(), &eucLen);
//変換結果の検証
if (result != S_OK || eucLen == 0)
{
  std::puts("変換に失敗しました。");
  return 0;
}

というのが一連の流れになります。

以下のコードはShift_JIS(コードページ932)の文字列をEUC-JP(コードページ51932)に変換します。

#include <tchar.h>
#include <iostream>
#include <memory>
#include <boost/scoped_array.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
  typedef HRESULT WINAPI (*TConvertINetString)(LPDWORD lpdwMode, DWORD dwSrcEncoding, DWORD dwDstEncoding, LPCSTR lpSrcStr, LPINT lpnSrcSize, LPBYTE lpDstStr, LPINT lpnDstSize);

  //DLLの読み込み
  TDll dll("mlang.dll");
  if (!dll)
  {
    std::puts("DLLの読み込みに失敗しました。");
    return 0;
  }
  //関数のアドレスの取得
  FARPROC proc = GetProcAddress(dll, "ConvertINetString");
  if (!proc)
  {
    std::puts("関数のアドレスの取得に失敗しました。");
    return 0;
  }
  TConvertINetString ConvertINetString = reinterpret_cast<TConvertINetString>(proc);

  //変換準備
  DWORD mode = 0;
  AnsiStringT<932> sjis = "あいうえおかきくけこさしすせそたちつてと";
  int sjisLen = sjis.Length();
  int eucLen = sjisLen * 2 + 1;
  boost::scoped_array<char> euc(new char[eucLen]);
  ZeroMemory(euc.get(), eucLen);

  //変換
  HRESULT result = ConvertINetString(&mode, 932, 51932, sjis.c_str(), &sjisLen, euc.get(), &eucLen);
  //変換結果の検証
  if (result != S_OK || eucLen == 0)
  {
    std::puts("変換に失敗しました。");
    return 0;
  }
  //ファイルに保存
  std::unique_ptr<TFileStream> fs(new TFileStream("C:\\test.txt", fmCreate));
  fs->WriteBuffer(euc.get(), eucLen);

  return 0;
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください