差分

ナビゲーションに移動 検索に移動

DLL

5,459 バイト追加, 2013年8月22日 (木) 11:00
作成
'''DLL'''とは、[[Windows]]においてよく使う機能を[[ライブラリ]]にし、一個のファイルにしたものである。

==DLLの使い方==
test.dllのint test(int a)という関数を利用することを考える。

静的リンクの利点はプログラムが簡単になることだが、欠点はDLLがないと起動できなくなることなので、
拡張機能を提供するには向かない。

逆に、動的リンクの利点はDLLがなくてもプログラム内でエラー処理をすればいいことだが、
プログラムが若干複雑になるという欠点がある。
===[[C言語]]===
====静的リンク====
1.インポートライブラリを作成する
<pre>&gt;pexports test.dll > test.def
&gt;dlltool --dllname test.dll --input-def test.def --output-lib libtest.a</pre>
2.プログラムをコンパイルする
<source lang="c">
/* usetest.c */
#include <stdio.h>

/* DLLに付属のC言語用ヘッダがあれば、それを使うべきである */
__declspec (dllimport) int test(int a);

int main(void) {
int a;
scanf("%d",&a);
printf("%d\n",test(a));
return 0;
}
</source>
<pre>&gt;gcc -o usetest.exe usetest.c -L. -ltest</pre>

====動的リンク====
<source lang="c">
/* usetest_d.c */
#include <stdio.h>
#include <windows.h>

/* 関数ポインタの宣言 */
typedef int (*test_p)(int a);

int main(void) {
test_p test;
HMODULE hDll;
int a;
/* DLL自体の読み込み */
hDll=LoadLibrary("test.dll");
if(hDll==NULL) {
puts("DLL load error!");
return 1;
}
/* DLL内の関数の読み込み */
test=(test_p)GetProcAddress(hDll,"test");
if(test==NULL) {
puts("function test load error!");
FreeLibrary(hDll);
return 1;
}

scanf("%d",&a);
printf("%d\n",test(a));

/* DLLの開放 */
FreeLibrary(hDll);
return 0;
}
</source>
<pre>&gt;gcc -o usetest_d.exe usetest_d.c</pre>

===[[Hot Soup Processor|HSP]]3===
<pre>;使用するDLLの名前を設定する
#uselib "test.dll"
;命令として登録する
#func test_o "test" int
;関数として登録する
#cfunc test_f "test" int

in=0
input in,100,30,100
button goto "命令を実行",*useorder
button goto "関数を実行",*usefunc
stop
*useorder
test_o in
dialog "stat="+str(stat),0,"命令"
stop
*usefunc
dialog str(test_f(in)),0,"関数"
stop</pre>
===[[Microsoft Excel|Excel]]===
<pre>'使用するDLLと関数の宣言
'変数を値渡しする際は、ByValをつけないといけない
Private Declare Function test Lib "test.dll" (ByVal a As Long) As Long

Sub Auto_Open()
Dim rawInput As String
Dim inputValue As Long
'xlsファイルのあるディレクトリにあるDLLを使うのに必要
ChDrive ThisWorkbook.Path
ChDir ThisWorkbook.Path

rawInput = InputBox("aを入力", "DLLサンプル", "0")
If rawInput <> "" Then
inputValue = Val(rawInput)
MsgBox Str(test(inputValue)), vbOKOnly, "戻り値"
End If
End Sub</pre>
理論上はこれでできるはずだが、一部のDLLは読み込めないようである(後述)。

===[[Active Basic]] 5===
<pre>#console

Declare Function test Lib "test.dll" (a As Long) As Long

Dim a As Long
Dim result As Long
Input a
result=test(a)
Print result</pre>

==DLLの作り方==
[[Visual Studio|Visual C#]]を使用しても拡張子が.dllのファイルは作れるようだが、ここで扱うDLLとは別物のようである。
===C言語===
<source lang="c">
/* test_dll.h */
#ifndef TEST_DLL_H_GUARD
#define TEST_DLL_H_GUARD

/* WINAPIマクロを使用するのに必要 */
#include <windows.h>

/* おまじない */
#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else
# define DLLIMPORT __declspec (dllimport)
#endif

/* ここにエクスポートしたい関数のプロトタイプ宣言をDLLIMPORTを付けて書く */
/* DLLIMPORTと戻り値の型の間にWINAPIと書かないと、Excel2007では読み込めないようである。 */
/* C言語(静的/動的リンク、gcc4.7.2)およびHSP3.2ではWINAPIがあってもなくても読み込めるようである。 */
DLLIMPORT WINAPI int test(int a);

#endif
</source>
<source lang="c">
/* test_dll.c */
#include "dll.h"

/* おまじない */
BOOL APIENTRY DllMain (HINSTANCE hInst,DWORD reason,LPVOID reserved) {
return TRUE;
}

/* このあたりに関数の本体を書く */
DLLIMPORT WINAPI int test(int a) {
return a*a+a+1;
}
</source>
<pre>&gt;gcc -static -c test_dll.c -o test_dll.o -DBUILDING_DLL=1
&gt;dllwrap --output-def libtest.def --implib libtest.a test_dll.o --no-export-all-symbols --add-stdcall-alias -o test.dll</pre>
この方法ならインポートライブラリも同時に作成してくれるので、使用時に作り直す必要はない。

===Active Basic 5===
# 新規作成を押す
# 「プロジェクト」を選んでOKを押す
# プロジェクト名を入力し、「DLL - プロシージャ ライブラリ」を選択して次へを押す
# 次へを押す
# 完了を押す
# 表示されたコードのDllMain関数の定義の下に下記のソースコードを書く
# リリース コンパイルを押す
<pre>'エクスポートしたい関数のFunction/Subと名前の間にExportと書く
Function Export test(a As Long) As Long
test=a*a+a+1
End Function</pre>
これで作成したDLLもExcel2007で読み込めるようである。

==関連項目==
* [[スタティックリンクライブラリ]]
* [[ライブラリ]]
* [[クラスライブラリ]]
匿名利用者

案内メニュー