ほっしーの技術ネタ備忘録

技術ネタの備忘録です。基本的に私が忘れないためのものです。他の人の役にも立つといいなぁ。

Wintab の開発環境構築

なんか昔は SDK をダウンロードしてパスを通すだけで済んだんですが、
最近はそうでもないようで面倒です...

.h ファイルの入手

ワコムからリンクを辿ったデベロッパーズページにサンプルがあります。
これを展開すると Include ディレクトリにヘッダファイルが入っています。

http://www.wacomeng.com/windows/index.html

DLL の入手

ワコムデバイスドライバをインストールします。
すると System32 とか SysWOW64 とかに Wintab32.dll が入ります。
x86 版と x64 版の両方を入手しておきます。


入っていない場合はインストーラアーカイバで無理やり展開すると両方出てきます。

.lib ファイルの作成 - x64版

x64 版は非常に簡単。このページにあるやり方でOK。
http://konuma.txt-nifty.com/blog/2006/11/dlllib_5de9.html

C:\Wintab\Lib64> dumpbin /exports Wintab32.dll > Wintab32.def

このコマンドでひな形を作って

LIBRARY WINTAB32

EXPORTS
	WTClose
	WTConfig

適当なエディタでこんな感じのフォーマットに整えます。

C:\Wintab\Lib64> lib /def:Wintab32.def /machine:x64 /out:Wintab32.lib

最後に lib コマンドで Wintab32.lib を出力します。

.lib ファイルの作成 - x86

こちらは少し問題。
この DLL は実際には __stdcall 呼び出し規約で呼ばれる機械語が吐かれていますし、
ヘッダも __stdcall で宣言されています。


ところが、__stdcall で宣言された関数は内部で
引数のバイト数を付けた _func@arg 形式の関数を呼ぼうとしますが、
DLL のエクスポート名は単純に _func 形式になっているため、このままではリンクできません。


そこで、.def ファイルに細工をします。

LIBRARY WINTAB32

EXPORTS
	WTQueueSizeSet@8 = WTQueueSizeSet @85
	WTOpenA@12       = WTOpenA        @21
	WTInfoA@12       = WTInfoA        @20
	WTClose@4        = WTClose        @22

イコールの左側は "WTOpenA@12" で1つの文字列なのでスペースを入れてはいけません。
これが __stdcall 規約でエンコードされた関数名(コンパイラが期待する関数名)です。
イコールの右側は DLL で(実際に)エクスポートされている関数名とその序数です。


前者はその関数を呼ぶコードをコンパイルしてみれば、
リンカエラーのメッセージで分かります。後者は x64 と同様に

C:\Wintab\Lib32> dumpbin /exports Wintab32.dll

を眺めると書いてあります。


必要な分だけ書いたら x64 同様に lib コマンドで Wintab32.lib ファイルを作ります。

C:\Wintab\Lib32> lib /def:Wintab32.def /machine:x86 /out:Wintab32.lib

.lib ファイルを使わない方法

こんな面倒なことをしたくなければ、DLL だけ用意して、
LoadLibrary(), GetProcAddress() API でダイナミックロードしましょう。


GetProcAddress() はエンコードされた名前にかかわらず検索してくれますし、
呼び出し規約は戻り値を FARPROC からキャストするタイミングで(強制的に)合わせることになるので問題ありません。


というか、たぶんそれを期待してるのでこんな変なバイナリが流通してるような気がします。


でも私は MSVC 拡張の /DelayLoad を使いたいんです。(参照: id:Hossy:20090531)