よくCのヘッダファイルをD用へと変換する作業が非常に面倒くさいと言う人がいるが(2chあたりで)、実は慣れるとそんな面倒なものではない。
wxWidgets や前回やった作業の手順の一部を、少しだけだが晒してみる。*1


関数の定義は普通複数のヘッダファイルに分かれているので、

cpp32 root.h

のように、全てのヘッダファイルをインクルードしているヘッダファイルをプリプロセッサにかけてやろう。#define 等が消えて、関数定義が一つのファイルにまとめられるだろう。(ひとつにまとめたくない場合は、他の方法を模索せよ!)

たいてい、関数定義は

int        cbDockPane_BarPresent( cbDockPane _obj, void* pBar );
cbDockPane cbDockPane_Create( int alignment, void* pPanel );
cbDockPane cbDockPane_CreateDefault(  );
void       cbDockPane_Delete( cbDockPane _obj );

と規則的に並んでいるだろう。(規則的じゃなかったら手作業でできる規模かも)自分は、PeggyPad(xyzzy だと自分が書く正規表現がうまく通らない)を使って
^(.+?)[ ]*(\w+?)\((.*?)\).*  →  \1<>\2<>\3
のように一度置き換えてから、スクリプトで好きな形に整形するようにしている。.lib の暗黙的リンクなら、プリプロセッサかけた状態ですでに完成に近いが、たとえば DLL から LoadLibrary をする場合などはこれじゃあだめだ。

<?php
/*
  コマンドラインphp -q build.php f=gl32_func.txt t=loadgl.txt > loadgl.d
 */

include "htmltemplate.inc";

//error_reporting(1);

$filename = basename($_GET["f"]);
$tmplname = basename($_GET["t"]);

$tmpl["nowtime"] = date("Y/m/d H:i");
$tmpl["scriptname"] = basename(__FILE__);

foreach (file($filename) as $line) {
    $ret = $func = $_arg = "";
    list($ret, $func, $_arg) = array_map("trim", explode("<>", $line));
    if (strlen($_arg) > 0) {
        $arg = array_map("trim", explode(",", $_arg));
    }
    else {
        $arg = Array();
    }
    $variables = Array();
    foreach ($arg as $a) {
        list(, $var) = explode(" ", $a);
        if ($var[0] == "*") {
            $var = substr($var, 1);
        }
        array_push($variables, $var);
    }
    $arg_only_variable = join(", ", $variables);

    $tmpl["functions"][] = Array(
        "return" => $ret,
        "name" => $func,
        "arg" => $_arg,
        "arg_only_variable" => ($arg_only_variable ? $arg_only_variable : null),
        );
}

HTMLTemplate::t_Include($tmplname, $tmpl);

?>

のようなスクリプト*2を書いて、

private import dll;

static this() {
  DLL dll = new DLL("hoge.dll");  dll.load(cast(void**)&{val functions/name}, "{val functions/name}");}

extern (Windows):{val functions/return} function({val functions/arg}) {val functions/name};

というテンプレートファイルを食わせてやればいいのだ。




書いてて、非常に他人には役に立たないような気がしてきてここでやめておくっ(゜д゜)

*1:自分のやり方なので、これが一番というわけではない

*2:マニュアル見ないでスラスラ書けるスクリプトPHPしかないのがアレだ