我希望在我的C ++库中使用COM dll。 我想的方法是#import dll的.tlb文件,我这样做了:
#import "mycom.tlb" no_namespace
问题是,我不太清楚这个声明的位置。它应该在H文件或CPP文件中吗?或者stdafx.h文件? 我尝试将它放在.cpp文件中,仅用于测试。
在H文件中我声明了这个成员:
ILogicSecuredPtr m_pbLogic;
(其中ILogicSecured是我想在COM dll中使用的接口)
然后我在构造函数中添加了这个来实例化接口:
CoInitialize(NULL);
m_pbLogic(__uuidof(LogicSecured));
(其中LogicSecured是实现接口的对象的名称)
在析构函数中我添加了:
CoUninitialize();
无论我在哪里尝试放置#import声明,都无法编译。 它只是无法识别ILogicSecured对象。 我在H文件中收到此错误:
Error 2 error C2146: syntax error : missing ';' before identifier 'm_pbLogic'
我还应该提一下,当我在ILogicSecuredPtr声明的F12(在Visual Studio中)时,它会把我带到tlh文件就好了。所以我知道它认出来了。
我在这里做错了什么?
非常感谢。 Roey
答案 0 :(得分:3)
问题是,当编译器解析.h文件时,它还没有看到#import
。由于您的项目很小,最好将#import
放入stdafx.h
。
当您按F12时,Visual Studio使用形成的Intellisence数据库信息解析所有源,这些信息可能与编译顺序不同。因此,让Intellisence知道某些内容被声明并且编译器不能同时编译它是非常典型的。
答案 1 :(得分:2)
如果导入dll或tlb文件会导致预处理器生成tlh和tli文件。 如果tlb稳定,你也可以生成这两个文件并包含tlh标头,就好像它是一个普通的标题。
所以答案是将#import放在你要放置标题的位置,因为它被转换为tlh文件的包含。
我以下列方式使用它来使自己独立于MSADO15.dll的位置并将tlh文件添加到我的subversion中。
#ifndef __ADO__H
#define __ADO__H
#ifdef REBUILD_ADO_HEADER
#import "C:\Programme\Gemeinsame Dateien\system\ado\MSADO15.DLL" rename_namespace("MyAdoNamespace") rename("EOF","EndOfFile")
#else // REBUILD_ADO_HEADER
#include "MSADO15.tlh"
#endif // REBUILD_ADO_HEADER
// Define ADO Namespace as global
using namespace MyAdoNamespace;
#endif // __ADO__H
答案 2 :(得分:1)
除了您遇到的编译问题外,此设计还存在其他问题。
通常,C ++库不应该在它不创建的线程上初始化COM。这可能会导致一些令人讨厌,难以调试的副作用。请考虑更新库的接口规范,以指示使用某些方法或对象需要初始化COM。您还应指定所需的线程模型(STA,Free)。
那就是说 - 你需要注意的另一件事是在你的智能指针超出范围之前调用CoUnitialize()。这也可能导致一些难以调试的副作用。如果您在包含COM智能指针的对象的析构函数中调用CoUnitialize(),则需要在调用CoUnitialize()之前显式释放和分离指针。
玩得开心!