【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

EXEを作る (2)

id:n7shi:20110419の続きです。バイナリの中をオフセット指定でベタ書きするのは問題があります。名前でアクセスするためクラスを定義します。まずDOSヘッダです。

Public Class IMAGE_DOS_HEADER
    Public e_magic, e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc,
           e_ss, e_sp, e_csum, e_ip, e_cs, e_lfarlc, e_ovno,
           e_res(3), e_oemid, e_oeminfo, e_res2(9) As UShort
    Public e_lfanew%

    Sub write(pos%)
        pos = write16s(pos, e_magic, e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc,
                       e_ss, e_sp, e_csum, e_ip, e_cs, e_lfarlc, e_ovno)
        pos = write16s(pos, e_res)
        pos = write16s(pos, e_oemid, e_oeminfo)
        pos = write16s(pos, e_res2)
        write32(pos, e_lfanew)
    End Sub
End Class

これを使うことで、少し読みやすくなりました。

使用前
' dos header
writestr(0, "MZ")
write16(2, &H90)
write16(4, 3)
write16(8, 4)
write16(&HC, &HFFFF)
write16(&H10, &HB8)
write16(&H18, &H40)
write32(&H3C, &H80)
使用後
Dim dosh = New IMAGE_DOS_HEADER With {
    .e_magic = conv16("MZ"),
    .e_cblp = &H90,
    .e_cp = 3,
    .e_cparhdr = 4,
    .e_maxalloc = &HFFFF,
    .e_sp = &HB8,
    .e_lfarlc = &H40,
    .e_lfanew = &H80}
dosh.write(0)

利用側はすっきりしていますが、その手間がIMAGE_DOS_HEADER.writeに移っただけです。構造体が増えるたびにこのようなコードを書くのは面倒なので、次回はその辺を改善します。