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を作成してください。





戻る