Udostępnij za pośrednictwem


Porady: tworzenie klasycznego składnika COM za pomocą biblioteki WRL

Można użyć Biblioteka szablonów C++ środowiska wykonawczego systemu Windows (WRL) do tworzenia podstawowych składników modelu COM do użycia w aplikacji pulpitu, dodatkowo do korzystania z niej dla Windows Store aplikacji.Tworzenie składników COM WRL mogą wymagać mniejszej ilości kodu niż ATL.Aby uzyskać informacje dotyczące podzbiór COM który WRL obsługuje, zobacz Biblioteka szablonów języka C++ środowiska wykonawczego systemu Windows (WRL).

Dokument ten pokazuje sposób używania WRL Aby utworzyć podstawowy składnik modelu COM.Chociaż można używać mechanizm wdrażania, który najlepiej odpowiada Twoim potrzebom, dokument ten pokazuje również najprostszy sposób zarejestrować i zużywają składnik COM z aplikacji pulpitu.

Aby użyć WRL do utworzenia podstawowego składnika klasycznego modelu COM

  1. W programie Visual Studio, tworzenie Roztwór do próby ślepej projektu.Nazwa projektu, na przykład, WRLClassicCOM.

  2. Dodaj Projekt systemu Win32 do tego rozwiązania.Nazwa projektu, na przykład, CalculatorComponent.Na Ustawienia aplikacji wybierz opcję DLL.

  3. Dodaj Plik regionów (.idl) plik do projektu.Nazwa pliku, na przykład, CalculatorComponent.idl.

  4. Dodaj ten kod do CalculatorComponent.idl:

    import "ocidl.idl";
    
    [uuid(0DBABB94-CE99-42F7-ACBD-E698B2332C60), version(1.0)] 
    interface ICalculatorComponent : IUnknown
    {
        HRESULT Add([in] int a, [in] int b, [out, retval] int* value);
    }
    
    [uuid(9D3E6826-CB8E-4D86-8B14-89F0D7EFCD01), version(1.0)]
    library CalculatorComponentLib
    {
        [uuid(E68F5EDD-6257-4E72-A10B-4067ED8E85F2), version(1.0)]
        coclass CalculatorComponent
        {
            [default] interface ICalculatorComponent;
        }
    };
    
  5. W CalculatorComponent.cpp, zdefiniuj CalculatorComponent klasy.CalculatorComponent Klasa dziedziczy z Microsoft::WRL::RuntimeClass.Microsoft::WRL::RuntimeClassFlags<ClassicCom> Określa, że klasa pochodzi z IUnknown i nie IInspectable. (IInspectable jest dostępna tylko dla Store składniki aplikacji.) CoCreatableClass tworzy zakład dla klasy, które mogą być używane z funkcji takich jak Wywołanie funkcji CoCreateInstance.

    #include "stdafx.h"
    
    #include "CalculatorComponent_h.h"
    #include <wrl.h>
    
    using namespace Microsoft::WRL;
    
    class CalculatorComponent: public RuntimeClass<RuntimeClassFlags<ClassicCom>, ICalculatorComponent>
    {
    public:
        CalculatorComponent()
        {
        }
    
        STDMETHODIMP Add(_In_ int a, _In_ int b, _Out_ int* value)
        {
            *value = a + b;
            return S_OK;
        }
    };
    
    CoCreatableClass(CalculatorComponent);
    
  6. Użyć następującego kodu, aby zastąpić kod w dllmain.cpp.Ten plik definiuje funkcje eksportu biblioteki DLL.Te funkcje za pomocą Microsoft::WRL::Module klasy do zarządzania fabryk klas dla modułu.

    #include "stdafx.h"
    #include <wrl\module.h>
    
    using namespace Microsoft::WRL;
    
    #if !defined(__WRL_CLASSIC_COM__)
    STDAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _COM_Outptr_ IActivationFactory** factory)
    {
        return Module<InProc>::GetModule().GetActivationFactory(activatibleClassId, factory);
    }
    #endif
    
    #if !defined(__WRL_WINRT_STRICT__)
    STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv)
    {
        return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
    }
    #endif
    
    STDAPI DllCanUnloadNow()
    {
        return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
    }
    
    STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*)
    {
        if (reason == DLL_PROCESS_ATTACH)
        {
            DisableThreadLibraryCalls(hinst);
        }
        return TRUE;
    }
    
  7. Dodaj Pliku definicji modułów (o rozszerzeniu def) plik do projektu.Nazwa pliku, na przykład, CalculatorComponent.def.Ten plik zawiera linker nazwy funkcji, które mają zostać wywiezione.

  8. Dodaj ten kod do CalculatorComponent.def:

    LIBRARY
    
    EXPORTS
        DllGetActivationFactory PRIVATE
        DllGetClassObject       PRIVATE
        DllCanUnloadNow         PRIVATE
    
  9. Dodaj runtimeobject.lib do linii linker.Aby dowiedzieć się, jak to zrobić, zobacz Pliki .Lib — Wejście konsolidatora.

Aby wykorzystać składnik COM z aplikacji pulpitu

  1. Zarejestruj składnik COM z rejestru systemu Windows.W tym celu należy utworzyć plik wpisów rejestracji, nadaj mu nazwę RegScript.regi Dodaj następujący tekst.Zamień <dll-path> ze ścieżką biblioteki DLL — na przykład, C:\\temp\\WRLClassicCOM\\Debug\\CalculatorComponent.dll.

    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{E68F5EDD-6257-4E72-A10B-4067ED8E85F2}]
    @="CalculatorComponent Class"
    
    [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{E68F5EDD-6257-4E72-A10B-4067ED8E85F2}\InprocServer32]
    @="<dll-path>"
    "ThreadingModel"="Apartment"
    
    [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{E68F5EDD-6257-4E72-A10B-4067ED8E85F2}\Programmable]
    
    [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{E68F5EDD-6257-4E72-A10B-4067ED8E85F2}\TypeLib]
    @="{9D3E6826-CB8E-4D86-8B14-89F0D7EFCD01}"
    
    [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{E68F5EDD-6257-4E72-A10B-4067ED8E85F2}\Version]
    @="1.0"
    
  2. Uruchom RegScript.reg lub dodać go do swojego projektu POST-Build.Aby uzyskać więcej informacji, zobacz Wiersz polecenia zdarzenia sprzed kompilacji/zdarzenia po kompilacji — Okno dialogowe.

  3. Dodaj Win32 Console Application projektu do tego rozwiązania.Nazwa projektu, na przykład Kalkulator.

  4. Użyj tego kodu, aby zastąpić zawartość Calculator.cpp:

    #include "stdafx.h"
    
    #include "..\CalculatorComponent\CalculatorComponent_h.h" 
    
    const IID IID_ICalculatorComponent = {0x0DBABB94,0xCE99,0x42F7,0xAC,0xBD,0xE6,0x98,0xB2,0x33,0x2C,0x60};
    const CLSID CLSID_CalculatorComponent = {0xE68F5EDD,0x6257,0x4E72,0xA1,0x0B,0x40,0x67,0xED,0x8E,0x85,0xF2};
    
    // Prints an error string for the provided source code line and HRESULT 
    // value and returns the HRESULT value as an int. 
    int PrintError(unsigned int line, HRESULT hr)
    {
        wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
        return hr;
    }
    
    int wmain()
    {
        HRESULT hr;
    
        // Initialize the COM library.
        hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
        if (FAILED(hr))
        {
            return PrintError(__LINE__, hr);
        }
    
        ICalculatorComponent* calc = nullptr; // Interface to COM component. 
    
        // Create the CalculatorComponent object.
        hr = CoCreateInstance(CLSID_CalculatorComponent, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&calc));
        if (SUCCEEDED(hr))
        {
            // Test the component by adding two numbers. 
            int result;
            hr = calc->Add(4, 5, &result);
            if (FAILED(hr))
            {
                PrintError(__LINE__, hr);
            }
            else
            {
                wprintf_s(L"result = %d\n", result);
            }
    
            // Free the CalculatorComponent object.
            calc->Release();
        }
        else
        {
            // Object creation failed. Print a message.
            PrintError(__LINE__, hr);
        }
    
        // Free the COM library.
        CoUninitialize();
    
        return hr;
    }
    /* Output:
    result = 9
    */
    

Stabilne programowanie

Ten dokument używa do wykazania, że można używać standardowych funkcji COM WRL Autor składnik modelu COM i udostępnić go do innych technologii COM włączone.Można również użyć WRL typów, takich jak Microsoft::WRL::ComPtr w swojej aplikacji pulpitu zarządzać okresem istnienia COM i innych obiektów.Następujący kod używa WRL do zarządzania istnienia ICalculatorComponent wskaźnik.CoInitializeWrapper Klasy otoki RAII, który gwarantuje, że biblioteki COM jest zwalniane i gwarantuje również, że okres istnienia biblioteki COM przeżywają jest ComPtr obiektu inteligentnego wskaźnika.

#include "stdafx.h"
#include <wrl.h>

#include "..\CalculatorComponent\CalculatorComponent_h.h" 

using namespace Microsoft::WRL;

const IID IID_ICalculatorComponent = {0x0DBABB94,0xCE99,0x42F7,0xAC,0xBD,0xE6,0x98,0xB2,0x33,0x2C,0x60};
const CLSID CLSID_CalculatorComponent = {0xE68F5EDD,0x6257,0x4E72,0xA1,0x0B,0x40,0x67,0xED,0x8E,0x85,0xF2};

// Prints an error string for the provided source code line and HRESULT 
// value and returns the HRESULT value as an int. 
int PrintError(unsigned int line, HRESULT hr)
{
    wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
    return hr;
}

int wmain()
{
    HRESULT hr;

    // RAII wrapper for managing the lifetime of the COM library. 
    class CoInitializeWrapper
    {
        HRESULT _hr;
    public:
        CoInitializeWrapper(DWORD flags)
        {
            _hr = CoInitializeEx(nullptr, flags);
        }
        ~CoInitializeWrapper()
        {
            if (SUCCEEDED(_hr))
            {
                CoUninitialize();
            }
        }
        operator HRESULT()
        {
            return _hr;
        }

    };

    // Initialize the COM library.
    CoInitializeWrapper initialize(COINIT_APARTMENTTHREADED);
    if (FAILED(initialize))
    {
        return PrintError(__LINE__, initialize);
    }

    ComPtr<ICalculatorComponent> calc; // Interface to COM component. 

    // Create the CalculatorComponent object.
    hr = CoCreateInstance(CLSID_CalculatorComponent, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(calc.GetAddressOf()));
    if (SUCCEEDED(hr))
    {
        // Test the component by adding two numbers. 
        int result;
        hr = calc->Add(4, 5, &result);
        if (FAILED(hr))
        {
            return PrintError(__LINE__, hr);
        }
        wprintf_s(L"result = %d\n", result);
    }
    else
    {
        // Object creation failed. Print a message. 
        return PrintError(__LINE__, hr);
    }

    return 0;
}

Zobacz też

Koncepcje

Biblioteka szablonów języka C++ środowiska wykonawczego systemu Windows (WRL)