|
DLL呼び出し機能(Ver8.31対応版)
目次−
DLL呼び出し機能
DLL呼び出しの機能があります。
使い方は、
例 |
loaddll "sample.dll";
if( !result ) {
message "sample.dllのロードに失敗しました。";
endmacro;
}
#a = dllfunc( "SampleFunc", 10 );
message str(#a);
freedll;
|
のような感じになります。
- loaddll(文)
-
パラメータで指定されたdllをロードします。
複数のDLLを同時にロードすることはできません。
freedllしないままloaddll文を続けて実行すると、以前のdllは自動的に解放(freedll)されます。
ロードされるのは現在の秀丸エディタについてだけなので、nexthidemaru文等で他の秀丸エディタに切り替わった場合は改めてloaddllしなおす必要があります。
- freedll(文)
-
loaddllしたDLLを解放します。
freedllしないままマクロを終了すると、ロードしたdllはそのままロードされたままになります。
- dllfunc(関数)
-
第一パラメータで指定された呼び出し先名をDLLから探し、その関数を呼び出します。
第二パラメータ以降には、文字列、数値などが自由に記述できます。
DLLの返す値がそのままdllfunc関数の返り値となります。
- dllfuncstr(関数)
-
dllfunc関数と同じく、DLL内の関数を呼び出します。
DLLからは文字列型の値を受け取り、それを返します。
- dllfuncw(関数)(V8.00以降)
-
dllfuncのUnicode版です。
- dllfuncstrw(関数)(V8.00以降)
-
dllfuncstrのUnicode版です。
- loaddllfile(値)
-
既にloaddllされている場合、ロードされているDLLのファイル名を返します。
ロードされていない場合は何もない文字列を返します。
複数のDLLを扱う場合(V8.00以降)
- loaddll(関数)
-
loaddll文の代わりにloaddll関数を使うと、複数のDLLを同時に扱うことができます。
ロードされるのは現在の秀丸エディタについてだけです。nexthidemaru等で他の秀丸エディタに切り替わった場合は改めてloaddllしなおす必要があります。
V8.01以降ではnexthidemaru等で切り替えてloaddllを実行した元の秀丸エディタに戻ってきた場合は有効です。
返り値はDLLを識別する数値(識別値)が返ります。
失敗した場合は 0 が返ります。
例: #dll = loaddll( $filename );
- freedll(文)
-
freedll文に識別値のパラメータを付けると、loaddll関数で読み込んだDLLを解放します。
例: freedll #dll;
- dllfunc(関数)
- dllfuncstr(関数)
- dllfuncw(関数)
- dllfuncstrw(関数)
-
第一パラメータに識別値のパラメータを付けると、loaddll関数で読み込んだDLLの関数を呼ぶことができます。
この場合、第二パラメータが呼び出し先名、第三パラメータ以降がDLLの関数に渡すパラメータになります。
例: #ret = dllfunc( #dll, "FuncName", ... );
- getloaddllfile(関数)
-
識別値を指定して、DLLのファイル名を返します。
例: $ret = getloaddllfile( #dll );
- DLL側の関数の作り方
-
DLL側では、呼び出されたい関数を、以下のようにint型で宣言してください。
extern int SampleFunc();
C++言語で記述する場合には、
extern "C" int SampleFunc();
としておく必要があります。
パラメータを受け取りたい場合には、数値か文字列かに応じてintかchar*のパラメータを記述してください。
例えば
extern "C" int SampleFunc( int n, char* psz );
のように宣言した場合、秀丸マクロ側からは、
#a = dllfunc( "SampleFunc", 100, "test" );
のように呼び出すことが出来ます。
秀丸エディタ側ではパラメータの型チェックはしないので、数値の所に文字列を指定して呼び出したり、その逆をすると、DLL側での動作がおかしくなります。
パラメータの数が足りなかったり多かったりする場合もDLL側の動作がおかしくなりますが、DLL側が特に何もしない場合には秀丸エディタ側が異常になる(例えばスタックが壊れる)ことはありません。
文字列を返す関数を作りたい場合には、返り値をchar*型で宣言してください。
extern char* SampleFuncStr();
char*型で宣言した関数が返す値は、スタック上ではなく、固定のメモリ領域のアドレスでなくてはいけません。例えば、
char* SampleFuncStr() {
static char sz[100];
strcpy( sz, "test" );
return sz;
}
はOKですが、
char* SampleFuncStr() {
char sz[100];
strcpy( sz, "test" );
return sz;
}
は正しく動作しない恐れがあります。
char*型で宣言された関数を呼ぶには、dllfuncstr()関数を使います。
$a = dllfuncstr( "SampleFuncStr" );
- 浮動小数点数版秀丸エディタ用のDLLの作成
-
浮動小数点数版秀丸エディタ用のDLLは、数値のやりとりをすべてdouble型とし、さらに、"FLOATMACRO"というダミーの関数をexportしてください。
具体的には、
extern "C" void FLOATMACRO() {}
という関数を用意し、.defファイルでこの関数をexportすればいいです。
秀丸エディタ側は、この関数がexportされている場合は浮動小数点数版秀丸エディタ用のDLLと判断します。
浮動小数点数版のDLLの場合は、戻り値はdoubleになります。
extern double SampleFunc();
浮動小数点数版のDLLの場合は、数値はdoubleになります。
extern "C" double SampleFunc( double n, char* psz );
- 整数版秀丸エディタ用のDLLの作成
-
整数版秀丸エディタ用のDLLは、先ほどのFLOATMACROダミー関数をexportしないでおくだけでOKです。そして、数値の受け渡しはすべてint(またはlong)としてください。
整数版秀丸エディタ用のDLLは浮動小数点数版からも呼び出せます。
- Unicode版のDLLの作成
-
文字列をUnicodeで受け渡しするにはdllfuncw, dllfuncstrwを使います。(V8.00以降)
DLL側は、文字列のchar*の部分を、WCHAR*として関数を定義することでできます。
extern "C" int SampleFunc( int n, WCHAR* pwsz );
extern "C" WCHAR* SampleFuncStr( int n, WCHAR* pwsz );
- 64bit版のDLLの作成
-
64bit版の場合は、intの部分が全て__int64(またはINT_PTR)として作成してください。
- 既存のDLLやWindowsAPIを呼び出したい場合
-
今回追加したDLL呼び出し機能は、あくまで秀丸エディタ用に作成された形式のDLLのための機能であり、一般的なDLLの呼び出しや、WindowsAPIの呼び出しにはほとんど使えません。特に、WindowsAPIは呼び出し規約が_stdcallとなっているので呼び出せません。
そういうDLLを呼び出したい場合には、バイパス用のDLLを作成してください。
|