「DLL」の版間の差分
ナビゲーションに移動
検索に移動
imported>MikeCAT 細 (リンクを追加) |
imported>MikeCAT (→DLLの使い方: なでしこを追加) |
||
118行目: | 118行目: | ||
result=test(a) | result=test(a) | ||
Print result</pre> | Print result</pre> | ||
+ | |||
+ | ===[[なでしこ]]=== | ||
+ | <pre>●test(a)=DLL("test.dll","int test(int a)") | ||
+ | 「aを入力してください。」で数値入力。 | ||
+ | 引数はそれを整数変換。 | ||
+ | test(引数)をいう。</pre> | ||
==DLLの作り方== | ==DLLの作り方== |
2013年8月24日 (土) 12:23時点における版
DLLとは、Windowsにおいてよく使う機能をライブラリにし、一個のファイルにしたものである。
目次
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の作り方
Visual C#を使用しても拡張子が.dllのファイルは作れるようだが、ここで扱う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
- 新規作成を押す
- 「プロジェクト」を選んでOKを押す
- プロジェクト名を入力し、「DLL - プロシージャ ライブラリ」を選択して次へを押す
- 次へを押す
- 完了を押す
- 表示されたコードのDllMain関数の定義の下に下記のソースコードを書く
- リリース コンパイルを押す
'エクスポートしたい関数のFunction/Subと名前の間にExportと書く Function Export test(a As Long) As Long test=a*a+a+1 End Function
これで作成したDLLもExcel2007で読み込めるようである。