在C++中无注册激活.NET COM对象

C++中激活.NET编写的COM组件可以通过COM机制实现,而不需要在Windows注册表中注册COM服务器。本文将重点介绍如何在不使用注册表的情况下,通过编程方式激活和管理.NET COM对象。

概述

为了在C++无注册激活和管理.NET COM对象,需要执行以下步骤:

  • 在进程中加载并启动.NET运行时(如果尚未启动)。
  • 在应用程序域中实例化对象,提供程序集和类型名称。
  • 如果显式启动,则在不再需要时停止.NET运行时。本文将在程序启动时启动运行时,并在程序即将退出时停止运行时。

开始之前

为了执行上述步骤,需要使用几个COM对象和接口。为此,需要:

  • 导入mscorlib.tlb类型库。
  • 包含metahost.h头文件,并与mscoree.lib静态库链接。

为了使代码更易于使用(和重用),下面展示的所有实用代码将被放入一个名为ManagedHost.h的头文件中,该文件包含一个名为Managed的命名空间和一个名为Host的类。Host类的目的是在创建类实例时加载并启动.NET运行时,并在实例销毁时停止运行时(以RTTI方式),并实例化实现分派COM接口的对象。由于Managed::Host类处理.NET运行时的方式,应该只在程序中创建一个实例。如果它不符合应用程序要求,修改代码应该相当容易(例如,如果已经启动,则不启动运行时,或在某个点停止它)。

托管CLR

为了在进程中加载并启动CLR,需要执行以下步骤:

  • 使用CLRCreateInstance()函数创建实现ICLRMetaHost COM接口的类的实例。
  • 使用元主机对象及其GetRuntime()方法创建实现ICLRRuntimeInfo COM接口的类的实例,并指定特定的CLR版本。
  • 使用运行时信息对象及其GetInterface()方法创建实现ICorRuntimeHost COM接口的类的实例。
  • 使用运行时主机及其Start()方法启动CLR。

为了停止当前进程中CLR的运行,需要使用ICorRuntimeHost对象并调用Stop()。这会停止当前进程中运行时的代码执行。通常在进程结束时执行此操作并不必要,因为当进程存在时所有代码都会停止执行。

激活对象

要创建实现分派接口的COM类的实例,必须:

  • 使用ICorRuntimeHost接口的CurrentDomain()方法获取对当前域的引用。
  • 通过程序集和类名称创建指定类的实例。结果是指向_ObjectHandle接口的指针。
  • 使用对象句柄的Unwrap()方法获取实际底层对象的IDispatch接口指针。

以下方法是Managed::Host类的所有public成员。

使用代码

为了展示如何使用上述编写的代码,将使用之前文章中展示的相同代码,该文章是“通过COM在.NETC++之间互操作”。在该文章中,有一个示例如下:

#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; }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485