English help on website



DLL側の関数の作り方(Ver9.35対応版)
目次DLL呼び出し機能− DLL側の関数の作り方
DLL側の関数の作り方
DLLには32bit版と64bit版があります。
DLL側では、呼び出されたい関数を、32bit版ではint型、64bit版では__int64型の関数で宣言してください。
INT_PTRを使うと同じソースコードで記述できます。(またはintptr_t)
呼び出し規約は_cdeclです。
C言語の場合:
extern INT_PTR _cdecl SampleFunc();

C++言語の場合:
extern "C" INT_PTR _cdecl SampleFunc();

関数はエクスポートされている必要があります。
モジュール定義ファイル(拡張子.def)に書く場合:
EXPORTS
    SampleFunc

C++のソース上に書く場合:
extern "C" __declspec( dllexport ) INT_PTR _cdecl SampleFunc();

パラメータを受け取りたい場合には、数値か文字列かに応じてINT_PTRかchar*のパラメータを記述してください。
例えば
extern "C" INT_PTR _cdecl SampleFunc( INT_PTR n, char* psz );
のように宣言した場合、秀丸マクロ側からは、
#a = dllfunc( "SampleFunc", 100, "test" );
のように呼び出すことが出来ます。

秀丸エディタ側ではパラメータの型チェックはしないので、数値の所に文字列を指定して呼び出したり、その逆をすると、DLL側での動作がおかしくなります。
パラメータの数が足りなかったり多かったりする場合もDLL側の動作がおかしくなりますが、DLL側が特に何もしない場合には秀丸エディタ側が異常になる(例えばスタックが壊れる)ことはありません。
DLL側からは、Hidemaru_GetDllFuncCalledTypeでどのように呼ばれているか知ることができるので、誤った呼ばれ方をしている場合に、処理をせずエラーで返す関数を作ることができます。

文字列を返す関数を作りたい場合には、返り値をchar*型で宣言してください。
extern char* _cdecl SampleFuncStr();
char*型で宣言した関数が返す値は、スタック上ではなく、固定のメモリ領域のアドレスでなくてはいけません。例えば、

char* _cdecl SampleFuncStr() {
    static char sz[100];
    strcpy_s( sz, "test" );
    return sz;
}
はOKですが、

char* _cdecl SampleFuncStr() {
    char sz[100];
    strcpy_s( 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 _cdecl SampleFunc();

浮動小数点数版のDLLの場合は、数値はdoubleになります。
extern "C" double _cdecl SampleFunc( double n, char* psz );


整数版秀丸エディタ用のDLLの作成
整数版秀丸エディタ用のDLLは、先ほどのFLOATMACROダミー関数をexportしないでおくだけでOKです。そして、数値の受け渡しはすべてINT_PTRとしてください。
整数版秀丸エディタ用のDLLは浮動小数点数版からも呼び出せます。


Unicode版のDLLの作成
 文字列をUnicodeで受け渡しするにはdllfuncw, dllfuncstrwを使います。(V8.00以降)
 DLL側は、文字列のchar*の部分を、WCHAR*として関数を定義することでできます。
extern "C" INT_PTR _cdecl SampleFunc( INT_PTR n, WCHAR* pwsz );
extern "C" WCHAR* _cdecl SampleFuncStr( INT_PTR n, WCHAR* pwsz );


既存のDLLやWindowsAPIを呼び出したい場合
今回追加したDLL呼び出し機能は、あくまで秀丸エディタ用に作成された形式のDLLのための機能であり、一般的なDLLの呼び出しや、WindowsAPIの呼び出しにはほとんど使えません。特に、WindowsAPIは呼び出し規約が_stdcallとなっているので呼び出せません。
そういうDLLを呼び出したい場合には、バイパス用のDLLを作成してください。