文字化けを直す

先ほどのソースコードはUTF-8で保存されている。文字化けの原因はこれだ。

helloworld.c - UTF-8で保存

/*
 * Reference:
 *    https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-winmain
 */
#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
{
  return MessageBox(NULL, "新大陸へようこそ!", "はじめてのウィンドウプログラミング", 0);
}

現在、ドキュメントは文字コードUTF-8で保存されることが多い。ソースコードをUTF-8で保存しておくのは自然な流れだ。

歴史的な経緯となるが、Microsoftのツールやアプリケーションの中にはいまだにUTF-8をうまく扱ってくれないものがある。アプリケーションは対応しているものが増えているが、少なくともcl.exeは全自動というところまではいっていない。

対応方法はバージョンごとに異なるのだが、「Visual Studio Build Tools 2022」の場合には、オブジェクトファイルを生成する段階でソースコードファイルの文字コードを指定することで文字化けを解消できる。cl.exeに「/source-charset:utf-8」というパラメータを指定すればよい。次のような感じだ。

オブジェクトファイルの生成 (ソースコードファイルの文字コードがUTF-8であると指定)

cl.exe /c /source-charset:utf-8 helloworld.c

リンクは先ほどと同じでよい。

実行ファイルの生成

link.exe user32.lib helloworld.obj

nmakeのMakefileに反映させると、次のようになる。

文字コード指定も反映させたnmake用Makefile

CMD=    helloworld

CC= cl.exe
CFLAGS= /c /source-charset:utf-8

LINK=   link.exe
LIBS=   user32.lib
LFLAGS=

EXIST=  cmd.exe /C if exist

all:    build

build:  $(CMD).exe

$(CMD).exe: $(CMD).obj
    $(LINK) $(LFLAGS) $(LIBS) *.obj
    dir

.c.o:
    $(CC) $(CFLAGS) $*.c

run:    build
    $(CMD).exe

clean:
    $(EXIST) $(CMD).obj del *.obj
    $(EXIST) $(CMD).exe del $(CMD).exe
    dir

ビルドして実行すると、次のようになる。

  • メッセージダイアログ実行例 - 文字化けせずに成功

    メッセージダイアログ実行例 - 文字化けせずに成功

Visual Studioのような統合開発環境を使っていると、こうした問題は発生しなかったり、1つチェックを入れるといった作業で問題が解決したりする。直接コマンドを実行すると、このようにどこで何を指定しなければならないかがよくわかってくる。

参考