今回はNET FrameworkのアンマネージAPI経由で.NETのクラスを呼ぶ例です。と言っても、ABでうまくいっていない(謎のエラーの)ためVC++でのコードです。COMに由来するインタフェースやその使い方が数多く出てきますが、COMの力は使っていません。そのことはCoInitialize(Ex)を呼んでいないことから明らかです。

なお、これは.NET Framework 1.xのみでしか使えません。2.0ではまた別の方法に変わっていますがそれはまた今度。

#include <Mscoree.h>
#pragma comment(lib, "Mscoree.lib")
 
#import <Mscorlib.tlb>
 
void ListSample(mscorlib::IListPtr pList)
{
  pList->Add(1);
  pList->Add(2.5);
  pList->Add(L"Hello");
 
  mscorlib::ICollectionPtr pCollection = pList;
  long count = pCollection->Count;
  for (long i = 0; i < count; ++i)
  {
    _variant_t v = pList->Item[i];
    v.ChangeType(VT_BSTR);
    MessageBoxW(0, v.bstrVal, L"", 0);
  }
}
 
typedef _com_ptr_t<
    _com_IIID<ICorRuntimeHost, &__uuidof (ICorRuntimeHost)> >
    ICorRuntimeHostPtr;
 
int main()
{
  HRESULT hr;
 
  ICorRuntimeHostPtr pHost;
  hr = CorBindToRuntimeEx(L"v1.1.4322", 0, 0, CLSID_CorRuntimeHost,
    IID_ICorRuntimeHost, (void**)&pHost);
  if (FAILED(hr))
    return 1;
 
  pHost->Start();
 
  IUnknownPtr pUnkAppDomain;
  hr = pHost->GetDefaultDomain(&pUnkAppDomain);
  if (FAILED(hr))
    return 1;
 
  mscorlib::_AppDomainPtr pAppDomain = pUnkAppDomain;
  mscorlib::_ObjectHandlePtr pObjHandle = pAppDomain->CreateInstanceFrom(
    L"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\mscorlib.dll",
    L"System.Collections.ArrayList");
 
  ListSample(pObjHandle->Unwrap());
}

ようするにCorBindToRuntimeExで、CLR(共通言語ランタイム:.NET Frameworkの言わば核)を読み込み、_AppDomainのCreateInstanceFromでSystem.Collections.ArrayListの実体を作っています。そして、それをListSample関数に渡しているというわけです。

比較のためCOM版を示します。といってもmain関数のみです。ListSampleの中は変わりません。

int main()
{
  //アパートメントスレッドでも問題ない。
  //ArrayList のスレッディングモデルは"Both"のため。
  CoInitializeEx(0, COINIT_MULTITHREADED);
  {
    mscorlib::IListPtr pList(L"System.Collections.ArrayList");
    ListSample(pList);
  }
  CoUninitialize();
}

スポンサード リンク

この記事のカテゴリ

  • ⇒ .NET FrameworkのアンマネージAPI (2) 使ってみる (.NET Framework 1.x)
  • ⇒ .NET FrameworkのアンマネージAPI (2) 使ってみる (.NET Framework 1.x)