如何在Win32 DLL项目中调用WinRT组件?
在Win32 DLL中加载免注册WinRT组件的完整流程
一、核心前提
你的Win32 DLL必须自行处理WinRT的初始化和组件依赖声明,不能依赖宿主应用的任何配置——毕竟宿主可能是Electron、C#应用等无WinRT环境的程序。
二、具体实现步骤
1. 配置Win32 DLL项目
- 启用C++/WinRT:在项目属性中开启
C++/WinRT支持,无需手动生成头文件,C++/WinRT会直接解析winmd文件。 - 关闭自动WinRT注册:确保项目属性中
注册输出设置为否,避免依赖系统注册表。
2. 声明对WinRT组件的依赖(免注册)
在DLL的嵌入清单中添加WinRT组件的依赖声明,让系统能找到对应的winmd和运行时文件:
<?xml version="1.0" encoding="UTF-8"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyIdentity type="win32" name="YourWin32Dll" version="1.0.0.0" /> <!-- 声明依赖的WinRT组件 --> <dependency> <dependentAssembly> <assemblyIdentity type="winrt" name="YourWinRTComponent" version="1.0.0.0" processorArchitecture="x64" /> </dependentAssembly> </dependency> </assembly>
将此清单作为嵌入资源添加到DLL项目中,确保DLL自身携带依赖信息。
3. 初始化WinRT环境
在DLL的DllMain或自定义初始化函数中,手动完成WinRT环境初始化(宿主应用不会自动处理):
#include <winrt/base.h> BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // 根据组件需求选择多线程公寓(MTA)或单线程公寓(STA) winrt::init_apartment(winrt::apartment_type::multi_threaded); break; case DLL_PROCESS_DETACH: // 清理WinRT环境 winrt::uninit_apartment(); break; } return TRUE; }
4. 调用WinRT组件
直接通过C++/WinRT语法调用组件,无需手动生成头文件:
#include <winrt/YourWinRTComponent.h> void CallWinRTComponent() { // 创建组件实例并调用方法 auto component = winrt::YourWinRTComponent::YourClass(); component.YourMethod(); }
C++/WinRT会在编译时自动解析winmd文件,生成对应的代理代码。
5. 部署文件
将以下文件放在同一目录下:
- 你的Win32 DLL
- WinRT组件的winmd文件
- WinRT组件的运行时DLL(若为C++/WinRT开发的组件,会生成对应xxx.dll)
- (可选)WinRT组件的资源文件(如有)
这样无论哪个宿主应用加载你的DLL,系统都会通过DLL的嵌入清单找到依赖的WinRT组件,无需修改宿主应用。
三、解决winmd未生成头文件的问题
如果你之前用WRL或winmdidl工具生成头文件的方式遇到问题,建议直接切换到C++/WinRT:
- C++/WinRT不需要手动生成头文件,编译时自动解析winmd生成内联代理代码。
- 确保你的WinRT组件是标准WinRT组件,编译时生成了结构正确的winmd文件(可通过
dumpbin /headers命令验证)。
内容的提问来源于stack exchange,提问作者Venkatesan Thiyagarajan
相关产品推荐
相关产品推荐

