Udostępnij za pośrednictwem


Integracja z WRL (C++/CX)

Możesz swobodnie mieszać kod WRL z kodem środowisko wykonawcze systemu Windows C++ Template Library (WRL). W tej samej jednostce tłumaczenia można użyć obiektów zadeklarowanych z notacją do obiektu (^) biblioteki WRL i notacją inteligentnego wskaźnika WRL (ComPtr<T>). Należy jednak ręcznie obsługiwać wartości zwracane oraz kody błędów HRESULT biblioteki WRL i wyjątki biblioteki WRL.

Tworzenie listy WRL

Aby uzyskać więcej informacji na temat tworzenia i używania składników biblioteki WRL, zobacz środowisko wykonawcze systemu Windows biblioteki szablonów języka C++ (WRL).

Przykład

Poniższy fragment kodu demonstruje używanie bibliotek WRL i WRL do używania klas środowisko wykonawcze systemu Windows i badania pliku metadanych.

Przykład pochodzi z fragmentu kodu na forum Tworzenie aplikacji ze sklepu Microsoft Store. Autor tego fragmentu kodu oferuje następujące zastrzeżenia i stipulacje:

  1. Język C++ nie udostępnia określonych interfejsów API do odzwierciedlenia na środowisko wykonawcze systemu Windows typach, ale pliki metadanych systemu Windows (winmd) dla typu są w pełni zgodne z plikami metadanych CLR. System Windows udostępnia nowe interfejsy API odnajdywania metadanych (RoGetMetaDataFile), aby uzyskać dostęp do pliku winmd dla danego typu. Jednak te interfejsy API są ograniczone do deweloperów języka C++, ponieważ nie można utworzyć wystąpienia klasy.

  2. Po skompilowaniu kodu należy również przekazać plik Runtimeobject.lib i Rometadata.lib do konsolidatora.

  3. Ten fragment kodu jest przedstawiany tak, jak to jest. Oczekuje się, że będzie działać poprawnie, ale prawdopodobnie może zawierać błędy.

#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;
}

Zobacz też

Współdziałanie z innymi językami