Visual c++ 如何获得VC++;为COM对象自动生成精简智能指针包装器?
我正在尝试将COM接口导入VC++。COM对象来自一个名为IDEA的应用程序,但这并不容易让其他人来帮助我。所以我想,如果有人能给我指示,我将如何为Word做这件事,这将是相当的 IDEA确实有一个.tlb文件,但它似乎不完整。我可以使用python访问COM API,示例如下:Visual c++ 如何获得VC++;为COM对象自动生成精简智能指针包装器?,visual-c++,com,dllimport,Visual C++,Com,Dllimport,我正在尝试将COM接口导入VC++。COM对象来自一个名为IDEA的应用程序,但这并不容易让其他人来帮助我。所以我想,如果有人能给我指示,我将如何为Word做这件事,这将是相当的 IDEA确实有一个.tlb文件,但它似乎不完整。我可以使用python访问COM API,示例如下: if __name__ == "__main__": dbName = "Sample-Employees.IMD" idea = win32ComClient.Dispatch(dispatch="I
if __name__ == "__main__":
dbName = "Sample-Employees.IMD"
idea = win32ComClient.Dispatch(dispatch="Idea.IdeaClient")
db = idea.OpenDatabase(dbName) # open db
table_def = db.TableDef() # get table definition
CComPtr<IDispatch> p;
p = db;
CComVairant result;
p.Invoke("TableDef", &result);
使用.tbl文件,我可以得到如下结果:
#import "D:\Program Files (x86)\CaseWare IDEA\IDEA\Idea.tlb"
#include "x64\Debug\idea.tlh"
#include "x64\Debug\idea.tli"
void fn()
{
Idea::IIdeaClientPtr client;
auto db = client->OpenDatabase("Sample-Employees.IMD");
db-> // interface not defined
}
Intellisense将在db->
之后完成以下操作:AddRef
、GetIdOfNames
、GetTypeInfo
、GetTypeInfoCount
、Invoke
、QueryInterface
和Release
。因此,我指的是不完整的接口定义
现在,由于python示例说明了Idea.IdeaClient
,我也在word中看到了这一点(即word.application
),因此我认为可能会使用它。但是环顾四周,我似乎找不到使用#import
的参考。我见过它与CLSIDFromProgID
一起使用,但这是一种非常手动的机制。COM智能PTR更可取
使用VC++是否可能做到这一点?也许OpenDatabase返回
IDispatch
,但包含TableDef
的接口仍在TLB中定义。
在这种情况下,您需要将IDispatch
向下转换为I-something-containing-TableDef-method
< >使用<代码> QueryInterface < /Cord>调用从C++代码> IDISPATT/<代码>中获取派生接口,而不是C或C++的转换,如<代码> STATICESTCAST
否则,您将需要使用IDispatch::Invoke
。您得到的最佳帮助是来自ATL的CComPtr
,此模板专门化具有调用帮助程序,因此您可以执行以下操作:
if __name__ == "__main__":
dbName = "Sample-Employees.IMD"
idea = win32ComClient.Dispatch(dispatch="Idea.IdeaClient")
db = idea.OpenDatabase(dbName) # open db
table_def = db.TableDef() # get table definition
CComPtr<IDispatch> p;
p = db;
CComVairant result;
p.Invoke("TableDef", &result);
CComPtr p;
p=db;
结果满意;
p、 调用(“TableDef”和结果);
或者使用IDispatch::按原样调用
Python总是依赖于
IDispatch::Invoke
,不使用静态接口,这就是为什么它不会遇到这个问题。酷!明天我会试试,让你知道我是怎么做的。不幸的是,生成的.tlh
和.tli
文件不包含任何与此相关的内容。它们包含的唯一COM智能PTR是IIdea
,IIdeaClient
,IIdeaClient2
,IIdeaClient3
,IProjectManagement
,ICommonDialogs
,ITaskPusher
和IAudiconHelper
。好的,这很有趣。我能够使用#导入“progid:Idea.IdeaClient”
和#导入“progid:Idea.TableDef”
,它生成了4个文件:Idea.tlh
,Idea.tli
,comdb.tlh
和comdb.tli
。在comdb.tlh
内部定义了\u COM\u SMARTPTR\u TYPEDEF(ITableDef,uu uuidof(ITableDef))
,这意味着ITableDefPtr
也将被定义。不过还有一件事,尽管我手动包含了.tlh
和.tli
文件,但我从中得到的信息是,我不必这样做。你知道为什么会这样吗?应该不需要包含生成的文件,#import
指令都会生成.tlh/.tli,如果它们需要(重新)生成并包含它们。有些人喜欢注释掉#import指令以避免在每个构建中生成这些文件,然后是的,您需要手动包含.tlh/.tli。但标准流程仍然是#每次需要生成这些文件时导入并生成它们代码>声明和autodb=client->OpenDatabase(“sampleemployees.IMD”)代码>语句,您的QueryInterface
cast可能如下所示:db.QueryInterface(u_uidof(ITableDef),&table_def)代码>可以使用本页所述内容。谢谢@ KuniF,但是我正在尝试找到一个工具来在COM对象周围生成一个瘦的C++包装,不仅暴露了接口,而且如果接口中的东西使用不正确,就会有硬编译错误。