在C++中激活.NET编写的COM组件可以通过COM机制实现,而不需要在Windows注册表中注册COM服务器。本文将重点介绍如何在不使用注册表的情况下,通过编程方式激活和管理.NET COM对象。
为了在C++中无注册激活和管理.NET COM对象,需要执行以下步骤:
为了执行上述步骤,需要使用几个COM对象和接口。为此,需要:
为了使代码更易于使用(和重用),下面展示的所有实用代码将被放入一个名为ManagedHost.h的头文件中,该文件包含一个名为Managed的命名空间和一个名为Host的类。Host类的目的是在创建类实例时加载并启动.NET运行时,并在实例销毁时停止运行时(以RTTI方式),并实例化实现分派COM接口的对象。由于Managed::Host类处理.NET运行时的方式,应该只在程序中创建一个实例。如果它不符合应用程序要求,修改代码应该相当容易(例如,如果已经启动,则不启动运行时,或在某个点停止它)。
为了在进程中加载并启动CLR,需要执行以下步骤:
为了停止当前进程中CLR的运行,需要使用ICorRuntimeHost对象并调用Stop()。这会停止当前进程中运行时的代码执行。通常在进程结束时执行此操作并不必要,因为当进程存在时所有代码都会停止执行。
要创建实现分派接口的COM类的实例,必须:
以下方法是Managed::Host类的所有public成员。
为了展示如何使用上述编写的代码,将使用之前文章中展示的相同代码,该文章是“通过COM在.NET和C++之间互操作”。在该文章中,有一个示例如下:
#include
#import "ManagedLib.tlb"
struct COMRuntime {
COMRuntime() { CoInitialize(NULL); }
~COMRuntime() { CoUninitialize(); }
};
int main() {
COMRuntime runtime;
ManagedLib::ITestPtr ptr;
ptr.CreateInstance(L"ManagedLib.Test");
if (ptr != nullptr) {
try {
ptr->TestBool(true);
ptr->TestSignedInteger(CHAR_MAX, SHRT_MAX, INT_MAX, MAXLONGLONG);
}
catch (_com_error const& e) {
std::wcout << (wchar_t*)e.ErrorMessage() << std::endl;
}
}
return 0;
}
使用上面的Managed::Host类,这个示例代码将更改为以下内容:
#include
#import "ManagedLib.tlb"
#include "ManagedHost.h"
int main() {
Managed::Host host;
ManagedLib::ITestPtr ptr = host.GetComObject(L"ManagedLib", L"ManagedLib.Test");
if (ptr != nullptr) {
try {
ptr->TestBool(true);
ptr->TestSignedInteger(CHAR_MAX, SHRT_MAX, INT_MAX, MAXLONGLONG);
}
catch (_com_error const& e) {
std::wcout << (wchar_t*)e.ErrorMessage() << std::endl;
}
}
return 0;
}