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