Postupy: Vytvoření klasické komponenty COM s použitím knihovny WRL
Lze použít Knihovna šablon C++ prostředí Windows Runtime (WRL) Chcete-li vytvořit základní klasické komponenty modelu COM pro aplikaci desktop apps, dále použít pro Windows Store apps.Pro vytváření komponent modelu COM WRL může vyžadovat méně kódu než knihovnu ATL.Informace o dílčí COM, WRL podporuje, naleznete v Knihovna šablon C++ prostředí Windows Runtime (WRL).
Tento dokument ukazuje, jak použít WRL Chcete-li vytvořit základní komponenty modelu COM.Přestože lze použít mechanismus pro nasazení, který nejlépe vyhovuje vašim potřebám, tento dokument také ukazuje základní způsob, jak se zaregistrovat a využívat komponenty modelu COM z pracovní plochy aplikace.
Chcete-li použít WRL Chcete-li vytvořit základní komponenty klasického modelu COM
V aplikaci Visual Studio vytvořte Slepého projektu.Název projektu, například WRLClassicCOM.
Přidat Projekt Win32 řešení.Název projektu, například CalculatorComponent.Na Nastavení aplikace vyberte knihovny DLL.
Přidat Soubor Midl (.) soubor do projektu.Zadejte název souboru, například CalculatorComponent.idl.
Přidáte tento kód 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; } };
Definovat v CalculatorComponent.cpp, CalculatorComponent třídy.CalculatorComponent Třída dědí z Microsoft::WRL::RuntimeClass.Microsoft::WRL::RuntimeClassFlags<ClassicCom> Určuje, že třída je odvozena z IUnknown a IInspectable. (IInspectable je k dispozici pouze Store komponenty aplikace.) CoCreatableClass vytvoří factory pro třídy, které lze použít s funkcemi, jako například funkce 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);
Pomocí následujícího kódu nahraďte kód v dllmain.cpp.Tento soubor definuje export funkcí knihovny DLL.Pomocí těchto funkcí Microsoft::WRL::Module ke správě zdrojů tříd pro modul třídy.
#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; }
Přidat Souboru s definicí modulu (.def) soubor do projektu.Zadejte název souboru, například CalculatorComponent.def.Tento soubor poskytuje propojovací program názvy funkcí, které mají být exportovány.
Přidáte tento kód do CalculatorComponent.def:
LIBRARY EXPORTS DllGetActivationFactory PRIVATE DllGetClassObject PRIVATE DllCanUnloadNow PRIVATE
Přidáte runtimeobject.lib do řádku propojovacího programu.Chcete-li zjistit, jak zobrazit Soubory .Lib jako vstup linkeru.
S potěšením komponenty modelu COM z pracovní plochy aplikace
Zaregistrujte komponenty modelu COM registru systému Windows.Chcete-li to provést, vytvořte soubor registrační položky, název RegScript.rega přidejte následující text.Nahradit <dll-path> cesta knihovny DLL, například 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"
Spustit RegScript.reg nebo ho můžete přidat do projektu Události po sestavení.Další informace naleznete v tématu Dialogové okno Příkazový řádek události před sestavením/po sestavení.
Přidat Aplikace konzoly Win32 projekt do řešení.Název projektu, například Kalkulačka.
Tento kód použijte, chcete-li nahradit obsah 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 */
Robustní programování
Tento dokument používá standardní funkce COM k prokázání toho, že lze použít WRL vytvářet komponenty modelu COM a zpřístupnit všechny technologie COM povolen.Můžete také použít WRL typy, jako Microsoft::WRL::ComPtr ve vaší plochy aplikace ke správě platnosti modelu COM a jiných objektů.Následující kód používá WRL ke správě platnosti ICalculatorComponent ukazatele.CoInitializeWrapper Třída je RAII obal, který zaručuje, že knihovny modelu COM je uvolněno a také zaručuje, že existence knihovny COM outlives ComPtr inteligentní ukazatel objektu.
#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;
}