DLL作成のTips
戻る
DLLの作り方
- メインソースにwindows.hをインクルードする(必要であればWindowsx.hも)
- ソースに工夫を加える
具体的には,
a. main()の代わりにdllmain()を使う
b. dllmainとエクスポートする関数の全てに__declspec(dllexport)とWINAPIをつける.
…例…
__declspec(dllexport) void WINAPI dllmain(void){}
__declspec(dllexport) BOOL WINAPI foo(int x,int y)
{
if (x==y)return 1;
return 0;
}
- 必要であればdefファイルを作成する
VC互換のDLLを作成する場合defファイルが必要です.
…書式…
EXPORTS
_(関数名)@(数値)=(関数名)
_(関数名2)@(数値2)=(関数名2)
これをエクスポートする関数全てについて記述する.
数値は通常は通し番号だが,呼び出すアプリケーションによっては
固定の番号を指定する必要がある事もある.それについては各自ド
キュメントを参照して下さい.
…例…
何か計算する関数,keisan(int x,int y)を呼び出せるようにしたいとき.
EXPORTS
_keisan@0=keisan
- bccをオプション指定して実行する
DLLファイルを作成するためにリンク時に-WDをつける.
…例…
メインソースファイル名がfoo.cの場合.
一.手作業の例
a.まずオブジェクトファイルを作成する
bcc32 -c foo.c
b.次にそれをDLL形式でリンクする(カッコ部分はdefファイルを作成した場合だけ書く)
bcc32 -WD -e foo.dll foo.obj (foo.def)
c.必要であればライブラリファイル(.lib)を作成する.
implib foo.lib foo.dll
二.makefileの例(カッコ部分はdefファイルを作成した場合だけ書く)
foo.dll:foo.obj (foo.def)
bcc32 -WD -e foo.dll foo.obj (foo.def)
implib foo.lib foo.dll
fool.obj:foo.c
bcc32 foo.obj -c foo.c
- できあがり。あとはテストをするだけです.
戻る
DLLの作り方
GCCについてはDLL作成のリファレンスが少ない気がします.
実はそれがこの資料を載せようと思うに至った理由でした.
注意:実行に成功しない場合-mrtdをコンパイラオプションにつけて下さい.気になる
ドキュメントを見たのですが,現在確認していません.(ちなみに-mrtdはGCCのオプションで,
関数に渡された引数のPopを自動で行ってくれるものです)
- 関数定義ヘッダファイルを用意する
例)foo.cで定義する関数の関数定義ヘッダファイルをfoo.hとする場合
{foo.c}
#include "foo.h"
void test (void){/*適当な処理*/}
char *test2(int a,int b)
{
char *c;
// :
//適当な処理
// :
return c;
}
{foo.h}
void test(void);
char *test2(int a,int b);
- メイン関数をWINAPI DllMain()とする(例…int WINAPI DllMain(){return TRUE;})
メイン関数を用意しない場合は、コンパイラが自動的にDllMain関数を作成するなので、
メイン関数は省略可能です。
- 利用したい関数をソースに記述する.
…例…
test.def
-->
- まずgccかg++でオブジェクトファイル(*.o)を作成する.
…例…
一. gcc -o foo.o -c foo.cならソースfoo.cからオブジェクトファイルfoo.oを作成する.
(mrtdが必要という記事を読みました.複数呼び出しを有効にするという意味?)
オブジェクトファイルならアセンブラ(as/*.asm)でもリソースファイル(windres/
*.rc)でもOKです.
二. makefileで foo.o:foo.c と記述する,etc.
- リンカオプション(gcc -Wl,option)を用いてDLL用を再配置可能にするための一時ファイル(=base.tmp)をオブジェクトから作成する
…書式…
gcc -mdll -o junk.tmp -Wl,--base-file,base.tmp {前項で作成したオブジェクトファイル(例:foo.o)}
rm junk.tmp
注: ここでjunk.tmpは不要なので削除してよい。
- 出力定義ファイル(defファイル)を作成する
…書式…
EXPORTS
関数名1
関数名2
:
:
例)foo.def (void test(void),char * test2(long,long)をエクスポートさせたい場合)
EXPORTS
test
test2
- dlltoolを用いてbase.tmp・defファイルから、DLLにリンクするエクスポートテーブルを格納する一時ファイル(=temp.exp)を作成する。
…書式…
dlltool -l {インポートライブラリ名} --dllname {作成するDLL名} --base-file base.tmp --output-exp temp.exp --def {定義ファイル(*.def)}
rm base.tmp
注: ここでbase.tmpは不要になるので削除してよい。
(例)
dlltool -l libfoodll.a --dllname foo.dll --base-file base.tmp --output-exp temp.exp --def foo.def
rm base.tmp
- エクスポートテーブル格納ファイルとオブジェクトファイルを使って実際にDLLを作成する
gcc -mdll -o {作成するDLL名} {オブジェクトファイル名} -Wl,temp.exp
rm temp.exp
rm {オブジェクトファイル名}
注: ここでtemp.exp,オブジェクトファイルは不要になるので削除してよい。
- 完成。あとはテストするだけです
例) test.cからfoo.dllを利用する場合(インポートライブラリlibfoodll.aをリンク)。
1.foo.dllの関数定義ヘッダをtest.cでインクルードする。(#include "foo.h"など)
2.次のようなコマンドでライブラリのリンクとソースのコンパイルを実行する
gcc -o test.exe test.c -lfoodll
3.作成した実行可能ファイルを実行
test.exe
・なお,デバッグには-Wallオプション(warn all)と,それからGDBでデバッグする場合には-g
オプションが有効です.
・また,サイズ,速度の最適化には-O3オプションが有効です.
参考用資料:
dllwrapコマンドヘルプ(日本語版)
dlltoolコマンドヘルプ(日本語版)
戻る
DLLの作り方
- Win32 Dynamic-Link Libraryとして新規プロジェクト作成
- メインソースにWindows.hをインクルードする(必要であればWindowsx.hも)
- メイン関数をBOOL WINAPI DllMain()とする.
- メイン関数はreturn TRUE;のみでよい.
- 外部に提供する関数にはextern "C" を付ける.
…例…(int test(void)という関数を作成する場合)
extern "C" int test(void)
{
/* 何らかの処理 */
return 2;
}
- プロジェクトに"〜.def"(メインのcppファイルと同じ名前)を作成し、中身を以下のようにする
例)foo.def
EXPORTS
test
その他エクスポートする関数名
:
:
:
:
- プロジェクトにエクスポート関数定義用ヘッダファイルが無ければそれも作成する
例)foo.h
int test(void);
- そのままコンパイルすればDLLが作成できる
戻る