love! LOVEHINA - love2hina.net


カテゴリー

アーカイブ
2006/07/19 マネージとアンマネージの混在 .NET2編 その2

作成者: カテゴリー: 未分類

昨日の続き。
…続いちゃうの!?とか言わないでくださいw

/clrコンパイルオプションを外してコンパイルするのはDLLのエントリポイントですから、
COMコンポーネントDLLの場合だと以下の関数が該当すると思います。
・DllMain
・DllCanUnloadNow
・DllGetClassObject
・DllRegisterServer
・DllUnregisterServer
これらを1つのCPPファイルに書いてしまえば言い訳ですね。

書き書き…
のーみそコネコネ、コンパイルしてみよーw
というか、ぷよまん食べたくなったよ…もう、売ってないけど…

 Σ(´Д`lll)エラーデタw

COMのインターフェース内にマネージオブジェクトを埋め込んでいるのですが、
オブジェクトマップの関係上、そのインターフェイス定義をインクルードしなくてはなりません。

BEGIN_OBJECT_MAP(WMPSyncPlgComMap)
	OBJECT_ENTRY(CLSID_WMPSyncPlg, clsWMPSyncPlgInterface)
END_OBJECT_MAP()
extern "C" bool __stdcall DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
	switch (dwReason)
	{
	case DLL_PROCESS_ATTACH:
        ComModule.Init(WMPSyncPlgComMap, hInstance);
		break;
	case DLL_PROCESS_DETACH:
        ComModule.Term();
		break;
	}
	return true;
}

こんな感じでDllMainで初期化のために参照されるため、clsWMPSyncPlgInterfaceクラス定義内に、

class ATL_NO_VTABLE clsWMPSyncPlgInterface: 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<clsWMPSyncPlgInterface, &CLSID_WMPSyncPlg>,
    public IWMPPluginUI
{
//
// 途中かなり省略
//
private:
	CComPtr<IWMPCore>	m_ptrWMPCore;
	gcroot<iriverWMPSyncPlugin::frmMain ^>	m_objfrmMain; // ここでハンドルオブジェクトを定義できない
};

上記のように、マネージオブジェクトを配置することが出来ないようです…
仕方ありませんので、汎用的な(void *)などで置き換えておいてみました。
そして、実際のコーディング部分でこのポインタ部分にgcroot<>テンプレートを割り当ててみます。

clsWMPSyncPlgInterface::clsWMPSyncPlgInterface(void)
{
	System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::MTA;
	m_ptrWMPCore = NULL;
	m_ptrfrmMainGCRoot = new gcroot<iriverWMPSyncPlugin::frmMain^>;
	*(gcroot<iriverWMPSyncPlugin::frmMain^> *)m_ptrfrmMainGCRoot = nullptr;
}

お、コンパイルも通り、実行が出来ました。
ヘッダ部分は、マネージ・アンマネージ両方から参照できるように作っておくと良いようです。

さてと、なんだか本当にこれで良いのか!?
…と思ったら、System.Runtime.InteropServicesが結構怪しいですね。
なんか、属性を付けるだけでCOMアプリケーションからアクセスできそうな予感w

今までのは何だったんだ!?

…これが試行錯誤くおりてぃ(まて