Integrazione WRL (C++/CX)
È possibile combinare liberamente il codice WRL con il codice WRL (Windows Runtime C++Template Library). Nella stessa unità di conversione è possibile usare oggetti dichiarati con notazione da handle a oggetto (^
) WRL e notazione smart pointer () WRL (ComPtr<T>
). È tuttavia necessario gestire manualmente i valori restituiti e i codici di errore HRESULT WRL e le eccezioni WRL.
Sviluppo WRL
Per altre informazioni sulla creazione e sull'utilizzo di componenti WRL, vedere Libreria di modelli C++ di Windows Runtime.For more information about authoring and consume WRL components, see Windows Runtime C++ Template Library (WRL).
Esempio
Il frammento di codice seguente illustra l'uso di WRL e WRL per utilizzare le classi di Windows Runtime ed esaminare un file di metadati.
L'esempio è tratto da un frammento di codice nel forum Building Microsoft Store apps (Compilazione di app di Microsoft Store). L'autore del frammento di codice presenta le seguenti dichiarazioni di non responsabilità e condizioni:
C++ non fornisce API specifiche da riflettere sui tipi Windows Runtime, ma i file di metadati di Windows (winmd) per un tipo sono completamente compatibili con i file di metadati CLR. Windows fornisce la nuova API di individuazione dei metadati (RoGetMetaDataFile) per ottenere il file .winmd per un determinato tipo. Tuttavia, queste API sono limitate all'uso da parte degli sviluppatori C++ perché non è possibile creare istanze di una classe.
Una volta compilato il codice, dovrai anche passare i file Runtimeobject.lib e Rometadata.lib al linker.
Questo frammento è riportato così com'è. I codice dovrebbe funzionare correttamente, ma potrebbe contenere degli errori.
#include <hstring.h>
#include <cor.h>
#include <rometadata.h>
#include <rometadataresolution.h>
#include <collection.h>
namespace ABI_Isolation_Workaround {
#include <inspectable.h>
#include <WeakReference.h>
}
using namespace ABI_Isolation_Workaround;
#include <wrl/client.h>
using namespace Microsoft::WRL;
using namespace Windows::Foundation::Collections;
IVector<String^>^ GetTypeMethods(Object^);
MainPage::MainPage()
{
InitializeComponent();
Windows::Foundation::Uri^ uri = ref new Windows::Foundation::Uri("http://buildwindows.com/");
auto methods = GetTypeMethods(uri);
std::wstring strMethods;
std::for_each(begin(methods), end(methods), [&strMethods](String^ methodName) {
strMethods += methodName->Data();
strMethods += L"\n";
});
wprintf_s(L"%s\n", strMethods.c_str());
}
IVector<String^>^ GetTypeMethods(Object^ instance)
{
HRESULT hr;
HSTRING hStringClassName;
hr = instance->__cli_GetRuntimeClassName(reinterpret_cast<__cli_HSTRING__**>(&hStringClassName)); // internal method name subject to change post BUILD
if (FAILED(hr))
__cli_WinRTThrowError(hr); // internal method name subject to change post BUILD
String^ className = reinterpret_cast<String^>(hStringClassName);
ComPtr<IMetaDataDispenserEx> metadataDispenser; ComPtr<IMetaDataImport2> metadataImport; hr = MetaDataGetDispenser(CLSID_CorMetaDataDispenser, IID_IMetaDataDispenser, (LPVOID*)metadataDispenser.GetAddressOf());
if (FAILED(hr))
__cli_WinRTThrowError(hr); // internal method name subject to change post BUILD
HSTRING hStringFileName;
mdTypeDef typeDefToken;
hr = RoGetMetaDataFile(hStringClassName, metadataDispenser.Get(), &hStringFileName, &metadataImport, &typeDefToken);
if (FAILED(hr))
__cli_WinRTThrowError(hr); // internal method name subject to change post BUILD
String^ fileName = reinterpret_cast<String^>(hStringFileName);
HCORENUM hCorEnum = 0;
mdMethodDef methodDefs[2048];
ULONG countMethodDefs = sizeof(methodDefs);
hr = metadataImport->EnumMethods(&hCorEnum, typeDefToken, methodDefs, countMethodDefs, &countMethodDefs);
if (FAILED(hr))
__cli_WinRTThrowError(hr); // internal method name subject to change post BUILD
wchar_t methodName[1024];
ULONG countMethodName;
std::wstring strMethods;
Vector<String^>^ retVal = ref new Vector<String^>();
for (int i = 0; i < countMethodDefs; ++i)
{
countMethodName = sizeof(methodName);
hr = metadataImport->GetMethodProps(methodDefs[i], nullptr, methodName, countMethodName, &countMethodName, nullptr, nullptr, nullptr, nullptr, nullptr);
if (SUCCEEDED(hr))
{
methodName[ countMethodName ] = 0;
retVal->Append(ref new String(methodName));
}
}
return retVal;
}