[D言語][Regnessem] あともうひといき。

 プラグインが認識されるとこまでいきました。
 もうちょっとでスケルトンが出来そう…



 昨日まで悩んでたのは、GetPluginInfo()が呼ばれたあと、
 Initialize()が呼ばれずにDLLがDetachされてしまうことでした。
 これはたぶんlpBufferへの文字列のコピーがうまく行ってないってことなので、
 そこら辺を調べてみることに。
 以下は公式サイトの開発室にあるC++用のコード。著作権等で問題があればご指摘ください。)

(略)
LPCTSTR PluginInfo[] = {
	NSM_API_VERSION,
	"Protocol/" MODULENAME,
	"Protocol Skeleton Plugin in VC++",
	"VC++ で作成したプロトコルプラグイン例",
	"Project Regnessem",
	"Copyright (c) 2004 Project Regnessem",
	"0.0.5",
};
(略)
int __stdcall GetPluginInfo(int nInfoNo, LPTSTR lpBuffer, int nSize)
{
	if ( nInfoNo < 0 || sizeof(PluginInfo)/sizeof(PluginInfo[0]) <= nInfoNo ) return 0;

	lstrcpyn(lpBuffer, PluginInfo[nInfoNo], nSize);
	return lstrlen(lpBuffer);
}
(以下略)

 まず配列の初期化には { } ぢゃなくて [ ] ですね。
 あとsizeof()はlengthプロパティで書き換えられるのか。
 それにD言語の文字列はNULL文字で終わらないから、
 コピーする前に末尾に付け足してやる必要があるな。
 LPCTSTRをconst char[]にしたほうがいいのかも。


 こうなるのか。

(略)
const char[][] PluginInfo = [
	NSM_API_VERSION,
	"Protocol/"~MODULENAME,
	"Protocol Skeleton Plugin in VC++",
	"VC++ で作成したプロトコルプラグイン例",
	"Project Regnessem",
	"Copyright (c) 2004 Project Regnessem",
	"0.0.5",
];
(略)
extern (Windows) int GetPluginInfo(int nInfoNo, LPTSTR lpBuffer, int nSize)
{
	if ( nInfoNo < 0 || PluginInfo.length <= nInfoNo ) return 0;

	PluginInfo[nInfoNo] ~= "\0";
	lstrcpyn(lpBuffer, PluginInfo[nInfoNo], nSize);
	return lstrlen(lpBuffer);
}
(以下略)

 PluginInfo[nInfoNo] ~= "\0";の部分で例外エラーだYO! 何故?
 …と思ったらDllMain()でgc_init()を呼んでいないのが原因でした。
 動的配列を使うにはGCが必須なのね。考えてみればあたりまえだけど。
 ちなみに以下のコードでもgc_init()の呼び出しが必須です。

char[] str1 = "abc", str2 = "def";
str1 ~= str2;




 ? ファイルサイズが26KB->63KBになっちゃったよ!
 うーん。。。ちょっと大きくなりすぎだな。
 今このスケルトンにはGCは要らない気がするんで、
 こう書いてみることにした。汚いけど。

const char[][] PluginInfo = [
	NSM_API_VERSION~\0,
	"Protocol/"~MODULENAME~\0,
	"Protocol Skeleton Plugin in VC++"~\0,
	"VC++ で作成したプロトコルプラグイン例"~\0,
	"Project Regnessem"~\0,
	"Copyright (c) 2004 Project Regnessem"~\0,
	"0.0.5"~\0,
];

 いけた!SimpleUIにもきちんと認識してもらえました。
 日本語も文字化けせずに表示されてます。
 良かった良かった。



 さて次は、サービスとイベントの登録!
 Regnessemに付属のデバッグウィンドウを開いてみませう。

Service:
  P

 アレ? おいらは"Protocol/Skelton_D/ShowOptionDialog"を登録したつもりなんだけど。

Event:
  S

 おいらは"System/OnModulesLoaded"をHookしたよ!!
 なぜ最初の一文字だけ?


 今日はもうギブアップ。_(_ _)_ここまで読んでくれた人ありがとう。