Dan*_*gro 8 c++ com visual-studio
我目前正在尝试构建一个与COM组件接口的C++库(DLL文件),以使其在Java中可用.我的想法是,我构建了一个非常小的C++ DLL,其中包含一个"包裹"COM组件的类,然后使用SWIG导出它.我使用#import语句得到了很多:
#import "ComponentName.dll"
Run Code Online (Sandbox Code Playgroud)
并调用CoInitialize()并创建组件的实例(通过Visual Studio生成的IComponentNamePtr类).这适用于所有正常的COM方法调用,这很好.
但是,我无法弄清楚如何使事件发挥作用.我看到有一个IComponentNameEventsPtr补充了主要的"智能指针"类,但我无法弄清楚要做些什么才能让它工作
我已经尝试了以下所有方法来使事件发挥作用:
有谁知道如何做到这一点?什么是最简单的方法?我的背景是C#和PHP,所以我在C++中使用COM的经验不多.
tldr:在C++ DLL中使用COM事件最简单的方法是什么?
实际上,我自己使用统一事件模型实现了这一点。我在让它发挥作用方面的经验中的一些注意事项:
您需要初始化 ATL,否则在挂接事件时会出现空指针错误。如果您不想在项目中使用 ATL(就像我一样 - 我的项目是纯 C++),则 dllmain.cpp 中类似的内容可以正常工作(使用虚拟模块初始化 ATL):
class CDummyModule : public CAtlDllModuleT<CDummyModule> {};
CDummyModule _Module;
Run Code Online (Sandbox Code Playgroud)您需要将“embedded_idl”添加到#import 行的末尾。
#import "ComponentName.dll" embedded_idl
Run Code Online (Sandbox Code Playgroud)如果组件中嵌入了任何结构,则由于 Visual Studio 中的错误,您可能会收到一些 MIDL2025 错误(“期望类型规范接近”)(请参阅https://connect.microsoft.com/VisualStudio/feedback/details/ 333473/midl2025-migration-an-attributed-com-project-to-vs-2008-pro-with-exported-structs和http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/ 03b78133-5eac-4754-b9af-fc864a9389a3)。解决方案是添加:
[importidl("vsbugfix.idl")];
Run Code Online (Sandbox Code Playgroud)然后添加一个
typedef struct StructName StructName;
Run Code Online (Sandbox Code Playgroud)
对于每个抛出错误的结构
完成后,您应该能够初始化 COM 并创建对象的实例。丑陋的示例代码:
IComponentName blah;
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
MessageBox(NULL, "Failed to initialize COM", "Hi!", 0);
throw "Failed to initialize COM";
}
try
{
hr = blah.CreateInstance("Something.Something");
if (FAILED(hr))
{
CoUninitialize();
MessageBox(NULL, "Failed to initialize the COM library!!", "Hi!", 0);
throw "Failed to initialize the COM library";
}
}
catch (...)
{
MessageBox(NULL, "Exception occured when initialising library!", "Error", 0);
CoUninitialize();
throw "Exception occured when initialising library!";
}
Run Code Online (Sandbox Code Playgroud)获得 COM 对象后,您可以按照 MSDN“COM 中的事件处理”一文连接事件:
__hook(&IComponentNameEvents::OnWhatever, blah, &EventHandlerClass::OnWhatever);
Run Code Online (Sandbox Code Playgroud)
请务必在调用 CoUninitialize() 之前取消挂钩所有事件,否则会出现错误。
| 归档时间: |
|
| 查看次数: |
5625 次 |
| 最近记录: |