- 概要
-
- ポーティング・プロジェクト
-
D言語で Windows API を使うには、ヘッダーファイルの移植が必要になります。
最小限のものは付属でありますが、本当に最小限で使えません。
Bindings for the Windows API などのポーティング・プロジェクトがありますし、それなりに使えますが、有志のプロジェクトでマメなメンテナンスは望めない様子だから、最新コンパイルでは修正が必要だったり、最新 OS の API を試したい場合は自力で何とかする必要があります。
とりあえず必要なものだけ手作業で追加して、誰かがまとものを作ってくれるのを待つ。というのが基本ですが、
- ポーティング・ツール
-
異種言語間のソースコードの完全移植は、互換性がない限り手作業でも無理でしょうから、変換ツールは補助的なもの以外ないのが普通ですが、
API のヘッダーファイルに特化すれば、完全移植は必要ありませんから、
- 変換が不可能、または、困難な場合スルーして OK
- 変換ファイルが特定できるので、対処療法的な補完が可能
- Windows Headers 専用ツール
-
最新 OS に対応するには、最新ポーティングが必要になりますが、
一度まともな変換が出来れば次にツールが必要になるのは、Windows SDK のバージョンアップかコンパイラの仕様変更に対応が必要になった時で、それも誰かが変換したファイルを公開すればそれで済みます。
- 仕様
-
- ファイル指定
- コマンドラインから、任意のファイル指定は出来ません。
- プリプロセッサ
-
-
#if、#ifdef -
versionやstatic ifへの置き換えは一切行わず、出来るだけ C の仕様通りにに展開。もし、コンパイル時に
version指定で切り替えたければ、例えば、
version( Unicode ){ pragma( lib, "win32.lib" ); import win32.windows; } else{ pragma( lib, "win32a.lib" ); import win32a.windows; }
とかじゃダメなの?
どちらにしても、筆者はversionなどへの変換は断念しました。 -
#define -
文字列置換に登録するかデータで判定。
文字列置換に登録しない場合、マクロは関数テンプレートに変換。
値の定義は
enum、キーワードが1対1の場合はaliasに変換し、それ以外は文字列置換に登録する。例えば
#define HOGE 100 #define FOO HOGE #define FOOS FOOS_FOO #define HOGE_MACRO( a, b ) a + b
を文字列置換に登録しなければ、
enum{ HOGE = 100, FOO = HOGE } alias FOOS_FOO FOOS; auto ref HOGE_MACRO( T0, T1 )( T0 a, T1 b ){ return a + b; }
-
-
struct -
- ネスト
- Conflict
-
typedef union _Foo{ struct { DWORD A; DWORD B; BYTE r[ 8 ]; } AA; struct { DWORD A; DWORD B; BYTE r[ 8 ]; } BB; struct { DWORD A; DWORD B; DWORD C; BYTE r[ 4 ]; } CC; } Foo;
union _FOO{ struct { DWORD A; DWORD B; BYTE r[ 8 ]; } struct CC_a{ DWORD A; DWORD B; DWORD C; BYTE r[ 4 ]; } CC_a CC; } alias _Foo Foo;
親がunionで衝突数とメンバー数が同じ場合、同じstructと判断して削除する。「同じではない」場合もあるかも知れないが、
unionなら問題にならない? - 継承
-
typedef struct Hoge : public Foo{ int x; };
は、
struct Hoge{ Foo _par_Hoge; alias _par_Hoge this; int x; }
- ビットフィールド
-
std.bitmanip.bitfieldsに置き換え。
-
enum -
そのまま変換しても、ヘッダー内で使われているメンバーに
enum名を付けてやれば問題ありませんが、メンバー名は重複していませんから、D で使う際もenum名は省略出来ます。-
メンバーを
alias宣言 (-ea) -
enum FOO{ A, B }
は、
enum FOO{ A, B } alias FOO.A A; alias FOO.B B;
かなり冗長なコードになるけど、自動ツールなら無問題。ただし
alias FOO.A A; alias A HOGE;
は NG だったりするからいまいち。
-
enum名をtypedefで宣言 (-et) -
enum FOO{ A, B }
は、
typedef typeof( 0 ) FOO; enum : FOO{ A, B }
alias宣言するより問題がなく、C のenumに最も近いと思うのだけど、typedefが本家リファレンスから削除されてるのがちょっと問題?
-
メンバーを
-
& -
C++ にある
&( 参照値 )は D では ”no equivalent” ですが、*( ポインター )扱いにするのが基本?引数の
&は、参照渡し(ref)にすればいいんでない?参照渡しがデフォルトですが、コマンドラインスイッチ(-tp)で出切り換え出来ます。 -
CONST -
interface -
- 変数
-
C++ では変数をポインタにしてるから、
interfaceの場合*を一つ減らす。 - インライン・メンバー関数
-
finalで実装。&を*にしていても、インライン・メンバー関数の&はrefになる。 -
IID -
EXTERN_C const IID IID_IUnknown; extern "C++" { MIDL_INTERFACE("00000000-0000-0000-C000-000000000046") IUnknown {
extern( C ){ const: IID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, [ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 ] };
- 未定義
-
未定義
structやinterfaceなどが引数にあったりします。どこかで定義されているのか、意味がいまいちわからないですし、そもそも使いようがない関数になるわけですから変換の必要がないのだと思いますが、Undefined の連鎖を嫌って、空の
structなどを定義しています。
- コンバーター
-
- インストール
-
変換済みファイル
- ソースコード
-
.\HtoD- ソースコードと実行ファイル。
-
.\HtoD\my - ソースコード
- サンプル
-
作者の好みに不満がなければ、変換済みファイルで問題ないはずですから、ツールを使う必要はありません。
-
.\HtoD\win32 -
デフォルト( Unicode )
whtod win32 -
.\HtoD\win32a -
ANSI
whtod win32a -a -
.\HtoD\win64 -
WIN64
whtod win64 -w64 -
.\HtoD\libs - ビルド済み各 .lib ファイル
-
.\HtoD\basic -
引数の
inとenumのtypedefをしていない、標準変換ファイル※ 検証は一切していません。
.\HtoD\windows.d
-
- 更新
-
- 2012年4月5日
6.42( 1149 ) -
- ラムダ式など試してみた
dwmapi追加
- 2012年2月20日
6.41( 1146 ) -
D 2.058対応-
castを不要にするためinterfaceの**をconst( hoge )*にした
-
- 2012年2月19日
6.40( 1140 ) -
D 2.058対応-
interface継承のpublicとか消した
-
- 2012年1月10日
6.39( 1134 ) -
D 2.057対応
-
6.38 -
- データ修正
-
oledb, oledlgをoleに -
iaccessをoleから
- 2011年11月6日
6.37( 1109 ) -
- 正規表現周りの修正、ちょっと高速化
- データ見直し
-
class登録 -
wsman追加
- 2011年11月4日
6.36( 1090 ) -
-
Macroチェックが機能していなかった -
複数行
Macro処理を修正 -
#undefなどの矛盾を回避できないスレッドを統合( deve.d, ana.d ) -
簡単な
template処理 -
struct処理を修正 -
class処理? -
fwcommon, wuapi, werapi, tspi, tapi3, searchapi, msp, encdec追加
-
- 2011年10月29日
6.35( 1033 ) -
-
D 2.056対応 -
typedefが使えなくされたから、デフォルトでenumはaliasにした -
Macro文字列置換処理の修正 - データの見直し
-
wrap処理の追加、修正 -
#defineのGUID変換は必要最小限に -
DEFINEGUID処理を修正 -
sapiddk, sti, iiscnfg, clusapi, indexsrv, ntquery, dbgeng, winternl, photoacquire、wab追加
-
- 2011年10月21日
6.34( 0966 ) -
- 数値の接尾辞などの処理を修正・統一した
-
d3d9, mfapi, oledb, wininet, mapi, lm修正 -
iaguid, capi, cryptuiapi, mileffects, cryptdlg, softpub, audiopolicy追加
- 2011年10月20日
6.33( 0951 ) -
- ※ GC の問題解決!!!、メモリ馬鹿食い解決!!
-
ks.d, mapi.d修正 -
wrap処理 -
audioclient, mfapi, d3d9, dxva, tdh追加
- 2011年10月16日
6.32( 0920 ) -
-
意味ない?
public importをprivateに -
patchapi, dinputd, xinput, wlanihv, uiautomationclient -
netmon,winsatcominterfacei, hliface, inetsdk -
shdeprecated, winfax, tuner, vidcap, ks追加 -
IID,CLSIDのexternは処理しないようにした -
複数文字
charリテラルの処理 -
std.string.wrapがダメだから、wrap処理してない・・・
-
意味ない?
- 2011年10月6日
6.31( 0864 ) -
-
Bindings for the Windows API にある
.d( 7.1 に.hがある )はほとんど追加した - 壊れてた
enumの型決定を修正 {}のある複数行Macroに対応-
const GUID -
#defineでのGUID -
Function解析などを修正 -
※
.libを分割した( コンパイラが落ちるから ) -
未使用
Macroをチェック -
#undefの処理を変えた -
intsafe.hをwinbase.dに読み込んだ (INT_MAXなどはそのままenumに ) - その他、追加ファイルで表面化したバグ修正や内部機能の追加など・・・
-
Bindings for the Windows API にある
- 2011年9月19日
6.30( 0694 ) -
-
inline Functionの解析・整形を統合した -
lmat.hをlm.dに -
raserror.h,mprapi.hをras.dに -
mapi.d,usp10.d,winldap.d追加
-
- 2011年9月16日
6.29( 0677 ) -
-
uxtheme.d,mmc.d,mmcobj.d,ras.d,rasdlg.d,raserror.d追加 - 文字列置換後の文字列置換を禁止( 無限ループ防止 )
-
enum処理のtemplate化などの修正
-
- 2011年9月13日
6.28( 0674 ) -
- 型登録を改善( 基本、省略はしない )
-
cast判定を改善 -
-uスイッチ追加
- 2011年9月5日
6.27( 0635 ) -
-
※
typedefでポインターが列挙されると、'*'が貯まっていたのを修正 - 型登録をまともにして、Conflict チェックも出来るようにした( ちょいオソ )
-
適当すぎな
cast判定をいくらかまともにした - データ構造を少し変更、ファイル挿入指定でフリーズすることがあったのを修正
-
shlobj.dにmshtml.hを読み込んだ -
winsock2.dでIPV6STRICTを define (wsipv6ok.hの読み込み ) -
http.d,oledlg.d,lm.d,drt.d,richole.d,textserv.d,p2p.d追加
-
※
- 2011年9月2日
6.26( 0574 ) -
シンボル管理は大改造したが、既存変換ファイルの変更は微小。
無駄な検索が減ったから、若干速くなった・・・若干
- 2011年8月27日
6.25( 0468 ) -
-
.\basicのメンテナンス -
-enでの Undefined を修正
-
- 2011年8月27日
6.24( 0462 ) -
-
-ccスイッチ追加
-
- 2011年8月25日
6.23( 0447 ) -
-
typedefで&の処理をしていなかったのを修正 -
structメンバーでinterfaceの処理をしていなかったのを修正
-
- 2011年8月24日
6.22( 0434 ) -
charのbyteへの置換をやめた-
SNDMSGを呼ぶ Macro はtemplate関数へ置き換えるようにした
- 2011年8月23日
6.21( 0420 ) -
※ 変換ファイルに大きな変更があります。
- 2011年8月17日
6.20( 0367 ) -
-
winnt.hと、winbase.h以外での関数オーバーロード -
interfaceのインライン・メンバー関数は挫折
-
- 2011年8月16日
6.19( 0343 ) -
conflictsになるのを修正
- 2011年8月16日
6.18( 0337 ) -
dwrite.dの追加- 読み込みだった
dcommonを.dにした - いくつかの
private importをpublicにした - その他修正
- 2011年8月11日
6.17( 0324 ) -
-
-oスイッチを追加、.libを.diとは別フォルダに作成できるようにした -
いつの間にか、エラーメッセージの行数表示が
0になっていた( 行数の更新 ) - 無名 Nest Struct のメンバー名衝突処理を修正。
-
- 2011年8月10日
6.16( 0304 ) -
-dを-iに変更、修正pragma( lib, )挿入周りの修正
- 2011年8月8日
6.15( 0292 ) -
-dを修正-p,-lスイッチの追加-
関数宣言に
exportを付けるようにした - 同名2重
externになっていたところを修正
- 2011年8月6日
6.14( 0283 ) - 2011年8月5日
6.13( 0281 ) -
-vスイッチの追加- 挿入コメント変更
- メンテナンスを考慮した修正
- 2011年8月3日
6.12( 0277 ) -
.hファイルの指定を修正- Nested Class、Template Class を出来るだけ使わないよう改造
core.thread.Thread.joinを使わないようにスレッドを改造GC.enableを挿入( メモリ食いは性分 )
GC がらみで落ちるのは解決できないが、大改造が少しは報われて、スレッドが走ってる時だけ
GC.disableで正常終了はするようにはなった。 - 2011年7月31日
6.11( 0267 ) -
- 実行ファイルを
whtodに改名 - データ参照を変更
-oスイッチ削除-sを-dに変更-f,-z,-ndelスイッチの追加
- 実行ファイルを
- 2011年7月31日
6.10( 0261 ) -
-m,-nmodスイッチの追加std.regexの置換問題を修正
- 2011年7月30日
6.09( 0253 ) -
.hファイルの PATH 指定でコメント表示が変だったのを修正
- 2011年7月30日
6.08( 0251 ) -
-hスイッチ( .h ファイルの PATH 指定 )追加- スレッド周りで意味不明なコードを削除
- 2011年7月27日
6.07( 0248 ) -
-w64,-s,-ndi,nlibスイッチの追加-w64変換をサンプルに追加
64bit 版は dmd の方がまだだから、今まで通りのコンパイルが通るのを確認しただけ、これで 64bit アプリが素直に動けば苦労が報われるわけだけど・・・
-
2011年7月25日
6.06( 0215 ) -
enum名を付けられるようにした-enスイッチの追加
GC がらみの対策でThreadをいじってみたが、挫折。元に戻した。
-
2011年7月23日
6.05( 0187 ) -
- 変換ファイルのコマンドライン指定はなしにした(固定)
-a,-ea,-cnスイッチの追加ANSI変換をサンプルに追加
-
2011年7月19日
6.04( 0157 ) -
.diファイルと.libファイルの自動作成を追加- サンプルライブラリを
win32.libに統合
-
2011年7月14日
6.03( 0154 ) -
D 2.054対応
-
2011年7月7日
6.02( 0151 ) -
- 進捗表示の変更など
- 2012年4月5日
- 変換実行
-
- コマンドライン
-
whtod 出力フォルダ -Switch ...
出力フォルダの指定は必至(
-m指定がなければ、モジュール・パッケージ名、-p指定がなければ、.lib ファイル名 )、.h ファイルのある場所で実行するか、.h ファイルのPATHを-hで指定します。Windows SDK がデフォルトでインストール済みなら指定は
-hだけで OK。 - Switch
-
-a-
ANSI
デフォルトでは
UNICODEがdefine。 -w32- デフォルト
-w64-
_M_AMD64,_WIN64 -v7- デフォルト
-vVista-vXP-v2K-cin-
デフォルト
const引数はinにする。結局、castでconstやimmutableを外すことになるのなら、いっしょ。煩わしくない分便利。
-cc-
引数の
constはconst。別に
inとかせんでも、普通にconstでも -cn-
引数の
constは無視する。本家の指示に従うなら・・・ -
-tr -
デフォルト
引数の
&を 記憶クラスrefにする。 -
-tp -
引数の
&は ポインター*にする。 -
-et -
デフォルト
enum名をtypedefで宣言して、名無しにする。 -
-ea -
enumメンバーをenum名を省略して使えるように、alias宣言する。 -en-
enumはそのまんま、何もしない。あえてenum名を使うメリットはないと思うが・・・ -ndi- コンパイル禁止
-nlib- コンパイル禁止
-nmod-
module宣言をしない。※ 自動コンパイルは全てキャンセルされる。
-p-
自動コンパイル時の .lib 名を指定。
デフォルトは出力フォルダ名。
無名の場合、コンパイルがキャンセルされる。
-o-
自動コンパイル時の .lib の出力フォルダ指定。
デフォルトは libs。
-ndel- テンポラリーファイルを削除しない。
-i-
.di ファイルのコピー先を指定。
指定
PATHにモジュール・パッケージ名を追加したPATHに移植した.diまたは.dファイルを全てコピーする。指定がなければコピーはしない。
-l-
.lib ファイルのコピー先を指定。
指定がなければコピーはしない。
-h-
ヘッダーファイル(
.h)のPATH指定。PATH指定がなければ Windows SDK のデフォルト"%Program Files%\Microsoft SDKs\Windows\v7.1\Include"が適用される。
-m-
モジュール・パッケージ名を指定。
指定がない(
-m)場合、モジュール・パッケージ名が省略される。自動コンパイルは全てキャンセルされる。
-f-
,区切りで.dのタブ、インデックス、最大幅の指定。-f4,8,120タブ:4、インデックス:8、最大幅:120-f,,120最大幅:120※ デフォルトは タブ:2、インデックス:4、最大幅:96
-z-
作業フォルダ(
.\tmp)を削除する。 -u-
template関数に変換した Macro のcastUndefined Symbol が無いかチェックする-debug でコンパイルされていると常に on
- 変換ファイル
-
-
windows -
Include Files : sdkddkver, winnls, wincon, winver, winreg, reason, winnetwk, wnnc,
cderr, dde, ddeml, dlgs, lzexpand, mmsystem, nb30, winperf, winsock, inaddr, wincrypt,
bcrypt, ncrypt, winefs, winscard, winioctl, winsmcrd, winspool, prsht, commdlg,
stralign, mcx, imm, ime_cmodes
winbase- Include Files : windef, winnt, basetsd, guiddef, cguid, winerror
wingdi- なし
winuser- なし
shellapi- なし
ole2- Include Files : rpc, rpcasync, objbase, rpcndr, rpcnsip, rpcsal, wtypes, unknwn, objidl, urlmon, oleidl, servprov, msxml, oaidl, propidl, oleauto
-
regstr - なし
-
shlobj -
Include Files : shlguid, isguids, exdisp, ocidl, docobj, shldisp, knownfolders,
shobjidl, propsys, propkeydef
commctrl- なし
-
wincodec - なし
-
richedit - なし
-
d2d1 -
Include Files : dcommon, d2derr, d2dbasetypes, dwrite
dxgiformat- なし
d3d10_1- Include Files : d3d10, dxgi, dxgitype, d3d10sdklayers, d3d10misc, d3d10shader, d3d10effect, d3d10_1shader
-
uiribbon - Include Files : uiribbonkeydef
-
http -
Include Files : ws2tcpip, ws2ipdef, in6addr
-
winsock2 - Include Files : ws2def, qos
-
-
strsafe -
strsafe.libが変換できない。そもそも、文字列関係だから不要?
-
- 既知の問題
-
-
マルチスレッドと GC がらみで落ちる -
マルチスレッドでの処理中GCが動くと落ちる。マルチスレッドで処理する時だけGC.disableで正常終了する。 -
#pragma intrinsic - 64bit では処理の必要がありそうなのだけど、基本無視して、コンパイルの通らないところだけ対処してる。
-
オーバーロードの禁止 -
関数は引数情報を持たないため、単に重複と判断してる。exportを優先してるから、致命的ではないが・・・・ -
pragma( lib, )の不足 - ちゃんとデータを作っていない・・・・・
- 検証
-
作者のオンリーワン環境( Windows7 64bit、AMD 6コア、8GBメモリ )でのみ動作確認。
その他の環境でどうなるかは予想も出来ない。
変換ファイルの検証も、簡単なプログラムでしか検証できていない。
-

