Windows Runtime Cpp ランタイムオブジェクト生成 新しいページはコチラ

提供: yonewiki
移動: 案内, 検索
(概要)
(Runtimeファクトリーの生成 RoGetActivationFactory)
 
1行: 1行:
 +
[[Windows Runtime Cpp]]へ戻る
 +
 +
 
== '''概要''' ==
 
== '''概要''' ==
 +
レジストリからDLLを検索し、必要なランタイムオブジェクトを生成するような仕組みによって生成されます。アクティベーションって言います。あるいはファクトリー呼ばれるものから生成するオブジェクトもあります。
 +
 +
== '''Runtimeオブジェクトの生成 RoActiveInstance''' ==
 +
 
RoActiveInstanceという関数でランタイムオブジェクトをDLLから生成できるようになっています。以下のように聞いたことのないようなIInspectable型変数を引数にとる形式になっています。
 
RoActiveInstanceという関数でランタイムオブジェクトをDLLから生成できるようになっています。以下のように聞いたことのないようなIInspectable型変数を引数にとる形式になっています。
  
 
*'''RoActiveInstance'''(HSTRING型変数, IInspectable型ポインタ変数のポインタ変数)
 
*'''RoActiveInstance'''(HSTRING型変数, IInspectable型ポインタ変数のポインタ変数)
  
第一引数:オブジェクトクラス名を保持したHSTRING型の変数です。
+
:第一引数:オブジェクトクラス名を保持したHSTRING型の変数です。45行目で使われています。サンプルでは"RuntimeClass.Windows.UI.Xaml.Application"というクラス名を持ったHSTRING変数としてHSTRING_StrClassNameが指定されています。
第二引数:IInspectable型の変数に生成されたランタイムオブジェクトを受け取ります。この変数はCOMの技術を継承した変数です。
+
:第二引数:IInspectable型の変数に生成されたランタイムオブジェクトを受け取ります。この変数はCOMの技術を継承した変数です。サンプルではIApplication型ポインタ変数のアドレス変数&pIApplicationObjを(IInspectable**)でキャストして引き渡しています。
  
  
106行: 113行:
 
_wsystem(L"pause");
 
_wsystem(L"pause");
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
125行: 131行:
 
  IID[8]=0-0-0-c000000046
 
  IID[8]=0-0-0-c000000046
 
  IID[9]=af86e2e0-b12d-4c6a-9c5ad7aa65101e90
 
  IID[9]=af86e2e0-b12d-4c6a-9c5ad7aa65101e90
 +
 +
続行するには何かキーを押してください . . .
 +
 +
 +
サンプルでは生成したランタイムオブジェクトのすべてのIIDをリストアップするプログラムになっています。なんかGUIDみたいな不気味なIDでカッコいいと思うのはマイクロソフトファンだけでしょうか?私の場合は9つもぶら下がってました。IIDはインタフェースIDと呼ばれています。GUIDの形式になっています。
 +
 +
 +
*ABI
 +
:Abstract Binary Interfaceで抽象バイナリーインターフェースの略。コードが混在するアプリケーション(C#、C ++、Cなど)を作成したり、いくつかの外部ライブラリを呼び出したりすると、データを渡すためのものとして、抽象バイナリインタフェース(ABI)というものが使用されます。Application Binary InterfaceもABIですが、アプリケーションがバイナリーと変換される境界という意味なので、ちょっと意味が違います。
 +
*XAML(ザムル)
 +
:Extensible Application Markup Languageの略。 マイクロソフトが開発したアプリ開発向けXMLですね。このXMLでUIを記述するような感じです。
 +
 +
== '''Runtimeファクトリーの生成 RoGetActivationFactory''' ==
 +
ファクトリーは具体的な機能を持ったランタイムのオブジェクトの生成に使う手法です。前項のオブジェクトが基本で、本項のオブジェクトが実用という感じです。ここではURIに関するオブジェクトを生成するファクトリーを作ってみます。さきほどのサンプルに追加する形で、ファクトリーによるオブジェクト生成を見てみます。プログラム自体は何の役にも立ちません。あしからず。ランタイムオブジェクトがあって、オブジェクトにはメソッドがあり、クラスのような働きをしてくれます。生成したIUriRuntimeClassFactoryオブジェクトにURI設定したオブジェクトを生成して、IUriRuntimeClassを生成します。
 +
 +
*'''RoGetActivationFactory'''(生成するオブジェクトクラス名,ランタイムオブジェクトのIIDインターフェースID,ランタイムオブジェクト型のアドレス変数のアドレス変数)
 +
:第一引数:生成するオブジェクトクラス名をHSTRING変数で指定します。サンプルでは85行目に使われています。HSTRING_StrURIClassNameのHSTRING型変数を指定しています。
 +
:第二引数:ランタイムオブジェクトのIIDで、通常はランタイムオブジェクトの型名を使って __iidof()関数で取得します。__iidof(IUriRuntimeClassFactory)として指定しています。
 +
:第二引数:ランタイムオブジェクト変数のアドレス変数のアドレス変数を(void**)型で指定します。voidですので、型指定無しのアドレス型ですね。 (void**)&pIUriRuntimeClassFactoryObjとして指定しています。
 +
 +
<syntaxhighlight lang="cpp" line start="1">
 +
#include <locale.h>
 +
#include <wchar.h>
 +
#include <stdio.h>
 +
#include <vector>
 +
#include <algorithm>
 +
#include <crtdbg.h>
 +
#include <roapi.h>
 +
#include <winstring.h>
 +
#include <windows.ui.xaml.h>
 +
 +
using namespace ABI::Windows::UI::Xaml;
 +
using namespace ABI::Windows::Foundation;
 +
 +
int main()
 +
{
 +
HRESULT hr;
 +
setlocale(LC_ALL, "");
 +
GetCurrentTime();
 +
 +
hr = RoInitialize(RO_INIT_TYPE::RO_INIT_MULTITHREADED);
 +
if (FAILED(hr)) {
 +
wprintf_s(L"初期化に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"初期化に成功しました。\n");
 +
}
 +
 +
const wchar_t *pcStrClassName = RuntimeClass_Windows_UI_Xaml_Application;
 +
const wchar_t *pcStrURIClassName = RuntimeClass_Windows_Foundation_Uri;
 +
const wchar_t *pcStrURI = L"http://www.yo-net.jp/";
 +
size_t sizeStrLength = wcslen(pcStrClassName);
 +
HSTRING HSTRING_StrClassName;
 +
HSTRING HSTRING_StrURIClassName;
 +
HSTRING HSTRING_StrURI;
 +
HSTRING HSTRING_StrHOST;
 +
HRESULT HRESULT_Hr;
 +
HRESULT_Hr = WindowsCreateString(pcStrClassName, sizeStrLength, &HSTRING_StrClassName);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"HSTRING_StrClassNameの生成に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"HSTRING_StrClassNameの生成に成功しました。\n");
 +
}
 +
 +
sizeStrLength = wcslen(pcStrURIClassName);
 +
HRESULT_Hr = WindowsCreateString(pcStrURIClassName, sizeStrLength, &HSTRING_StrURIClassName);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"HSTRING_StrURIClassNameの生成に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"HSTRING_StrURIClassNameの生成に成功しました。\n");
 +
}
 +
 +
sizeStrLength = wcslen(pcStrURI);
 +
HRESULT_Hr = WindowsCreateString(pcStrURI, sizeStrLength, &HSTRING_StrURI);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"HSTRING_StrURIの生成に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"HSTRING_StrURIの生成に成功しました。\n");
 +
}
 +
 +
 +
IApplication *pIApplicationObj;
 +
HRESULT_Hr = RoActivateInstance(HSTRING_StrClassName, (IInspectable**)&pIApplicationObj);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"HSTRING_StrClassNameのRuntimeObject生成に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"HSTRING_StrClassNameのRuntimeObject生成に成功しました。\n");
 +
}
 +
 +
IUriRuntimeClass *pIUriRuntimeClassObj;
 +
IUriRuntimeClassFactory *pIUriRuntimeClassFactoryObj;
 +
HRESULT_Hr = RoGetActivationFactory(HSTRING_StrURIClassName, __uuidof(IUriRuntimeClassFactory), (void**)&pIUriRuntimeClassFactoryObj);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"HSTRING_StrClassNameのRuntimeObject生成に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"HSTRING_StrClassNameのRuntimeObject生成に成功しました。\n");
 +
}
 +
 +
HRESULT_Hr = pIUriRuntimeClassFactoryObj->CreateUri(HSTRING_StrURI, &pIUriRuntimeClassObj);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"IUriRuntimeClassの生成に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"IUriRuntimeClassの生成に成功しました。\n");
 +
}
 +
 +
HRESULT_Hr = pIUriRuntimeClassObj->get_Host(&HSTRING_StrHOST);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"pIUriRuntimeClassObjからHOSTの取得に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"pIUriRuntimeClassObjからHOSTの取得に成功しました。\n");
 +
}
 +
wprintf_s(L"pIUriRuntimeClassObj HOST=%s\n",WindowsGetStringRawBuffer(HSTRING_StrHOST, nullptr));
 +
 +
 +
HSTRING HSTRING_GetStrClassName;
 +
HRESULT_Hr = pIApplicationObj->GetRuntimeClassName(&HSTRING_GetStrClassName);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"HSTRING_StrClassNameの取得に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"HSTRING_StrClassNameの取得に成功しました。\n");
 +
}
 +
 +
ULONG ULONG_IidCnt;
 +
IID *pIID_Iids;
 +
HRESULT_Hr = pIApplicationObj->GetIids(&ULONG_IidCnt, &pIID_Iids);
 +
if (FAILED(HRESULT_Hr)) {
 +
wprintf_s(L"IIDの取得に失敗しました。\n");
 +
_CrtDbgBreak();
 +
return 0;
 +
}
 +
else {
 +
wprintf_s(L"IIDの取得に成功しました。\n");
 +
}
 +
 +
for (ULONG ULONG_i = 0; ULONG_i < ULONG_IidCnt; ULONG_i++) {
 +
wprintf_s(L"IID[%d]=%x-%x-%x-", ULONG_i, (pIID_Iids + (int)ULONG_i)->Data1, (pIID_Iids + (int)ULONG_i)->Data2, (pIID_Iids + (int)ULONG_i)->Data3);
 +
for (int iN = 0; iN < 8; iN++) {
 +
wprintf_s(L"%x", *((pIID_Iids + (int)ULONG_i)->Data4 + iN));
 +
}
 +
wprintf_s(L"\n");
 +
}
 +
wprintf_s(L"\n");
 +
 +
CoTaskMemFree(pIID_Iids);
 +
pIUriRuntimeClassObj->Release();
 +
pIUriRuntimeClassFactoryObj->Release();
 +
pIApplicationObj->Release();
 +
 +
RoUninitialize();
 +
_wsystem(L"pause");
 +
}
 +
 +
</syntaxhighlight>
 +
表示結果
 +
初期化に成功しました。
 +
HSTRING_StrClassNameの生成に成功しました。
 +
HSTRING_StrURIClassNameの生成に成功しました。
 +
HSTRING_StrURIの生成に成功しました。
 +
HSTRING_StrClassNameのRuntimeObject生成に成功しました。
 +
HSTRING_StrClassNameのRuntimeObject生成に成功しました。
 +
IUriRuntimeClassの生成に成功しました。
 +
pIUriRuntimeClassObjからHOSTの取得に成功しました。
 +
pIUriRuntimeClassObj HOST=www.yo-net.jp
 +
HSTRING_StrClassNameの取得に成功しました。
 +
IIDの取得に成功しました。
 +
IID[0]=74b861a1-7487-46a9-9a6ec78b512726c5
 +
IID[1]=25f99ff7-9347-459a-9facb2d0e11c1af
 +
IID[2]=b3ab45d8-6a4e-4e76-a0d32d4643a9f1a
 +
IID[3]=19104be-522a-5904-f52fde721429e0
 +
IID[4]=db5cd2b9-d3b4-558c-c64e434fd1bd889
 +
IID[5]=b775ad7c-18b8-45ca-a1b0dc483e4b1028
 +
IID[6]=38-0-0-c000000046
 +
IID[7]=df0b3d60-548f-101b-8e65802b2bd119
 +
IID[8]=0-0-0-c000000046
 +
IID[9]=af86e2e0-b12d-4c6a-9c5ad7aa65101e90
 +
 +
続行するには何かキーを押してください . . .
 +
 +
 +
と、こんな感じで使います。ランタイムオブジェクトはこれだけではないので、IxxRuntimeClassFactoryやIxxRuntimeClassといったランタイムオブジェクトはいくつかありますので、それらについては少しづつ紹介していかねばらないのかなぁとは思っています。まずは使い方の一例を示しました。IxxRuntimeというようなオブジェクトだけに限らず、IDisplayPropertiesStaticsのようなオブジェクトもあります。
 +
 +
 +
オブジェクト生成後は
 +
*pIUriRuntimeClassObj->Release();
 +
*pIUriRuntimeClassFactoryObj->Release();
 +
*pIApplicationObj->Release();
 +
のような、それぞれのオブジェクトに準備されているRelease()メソッドを実行して解放してあげる必要があります。
 +
  
続行するには何かキーを押してください . . .
+
[[Windows Runtime Cpp]]へ戻る

2017年6月2日 (金) 00:00時点における最新版



個人用ツール
名前空間

変種
操作
案内
ツールボックス