DLL

提供: MonoBook
移動: 案内検索

DLL(読み:でぃーえるえる、語源:Dynamic Link Library)とは、Windowsにおいてよく使う機能をライブラリにし、一個のファイルにしたものである。

概要[編集]

かつてコンピューターリソースが乏しかった時代、複数のプログラムでひとつのライブラリを共有しようという夢のような概念が生まれた。 誰もが絶賛した。

だが、その先にあったのはDLL地獄であった。

人々は奪い合い、殺し合い、混沌だけが残った。

DLLの使い方[編集]

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

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

逆に、動的リンクの利点はDLLがなくてもプログラム内でエラー処理をすればいいことだが、 プログラムが若干複雑になるという欠点がある。

C言語[編集]

静的リンク[編集]

1.インポートライブラリを作成する

>pexports test.dll > test.def
>dlltool --dllname test.dll --input-def test.def --output-lib libtest.a

2.プログラムをコンパイルする

/* 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;
}
>gcc -o usetest.exe usetest.c -L. -ltest

動的リンク[編集]

/* 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;
}
>gcc -o usetest_d.exe usetest_d.c

HSP3[編集]

;使用する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

Excel[編集]

'使用する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

理論上はこれでできるはずだが、一部のDLLは読み込めないようである(後述)。

Active Basic 5[編集]

#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

なでしこ[編集]

●test(a)=DLL("test.dll","int test(int a)")
「aを入力してください。」で数値入力。
引数はそれを整数変換。
test(引数)をいう。

DLLの作り方[編集]

.NET Framework =[編集]

Visual C#を使用しても拡張子が.dllのファイルは作れるようだが、ここで扱うDLLとは別物である。

.NET Frameworkにおける.dllファイルはエントリポイントを持たない共通中間言語バイナリ表現であり、従来のDLLとはまったくの別物である。紛らわしいことに拡張子が一緒だがまったくの別物である。

ここだけの話、.NET Frameworkの.exeファイルは.dllファイルのように扱える。

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
/* 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;
}
>gcc -static -c test_dll.c -o test_dll.o -DBUILDING_DLL=1
>dllwrap --output-def libtest.def --implib libtest.a test_dll.o --no-export-all-symbols --add-stdcall-alias -o test.dll

この方法ならインポートライブラリも同時に作成してくれるので、使用時に作り直す必要はない。

Active Basic 5[編集]

  1. 新規作成を押す
  2. 「プロジェクト」を選んでOKを押す
  3. プロジェクト名を入力し、「DLL - プロシージャ ライブラリ」を選択して次へを押す
  4. 次へを押す
  5. 完了を押す
  6. 表示されたコードのDllMain関数の定義の下に下記のソースコードを書く
  7. リリース コンパイルを押す
'エクスポートしたい関数のFunction/Subと名前の間にExportと書く
Function Export test(a As Long) As Long
	test=a*a+a+1
End Function

これで作成したDLLもExcel2007で読み込めるようである。

関連項目[編集]