Compartir vía


Integración de WRL (C++/CX)

Puede mezclar libremente código WRL con código de biblioteca de plantillas Windows Runtime C++ (WRL). En la misma unidad de traducción puede usar objetos declarados con la notación WRL de tipo "indicador a objeto" (^) y la notación de puntero inteligente WRL (ComPtr<T>). Sin embargo, debes controlar manualmente los valores devueltos, los códigos de error HRESULT de WRL y las excepciones de WRL.

Desarrollo de WRL

Para obtener más información sobre la creación y el consumo de los componentes WRL, consulte Biblioteca de plantillas de Windows Runtime C++ (WRL).

Ejemplo

En el siguiente fragmento de código se muestra el uso de WRL y WRL para utilizar clases de Windows Runtime y examinar un archivo de metadatos.

El ejemplo está tomado de un fragmento de código del foro de creación de aplicaciones de la Tienda Microsoft. El autor de este fragmento de código proporciona los avisos de declinación de responsabilidades y las estipulaciones siguientes:

  1. C++ no proporciona API específicas para aplicar reflexión en tipos de Windows Runtime, pero los archivos de metadatos de Windows (.winmd) para un tipo son totalmente compatibles con los archivos de metadatos CLR. Windows proporciona las nuevas API de detección de metadatos (RoGetMetaDataFile) para obtener el archivo .winmd para un tipo determinado. Sin embargo, estas API son de uso limitado para los programadores de C++ porque no puedes crear instancias de una clase.

  2. Una vez compilado el código, también necesitarás pasar Runtimeobject.lib y Rometadata.lib al vinculador.

  3. Este fragmento de código se muestra tal cual. Aunque se espera que funcione correctamente, es posible que contenga errores.

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

Consulte también

Interoperación con otros lenguajes