昨日の続き。
…続いちゃうの!?とか言わないでください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
今までのは何だったんだ!?
…これが試行錯誤くおりてぃ(まて