Visual c++ 如何获得VC++;为COM对象自动生成精简智能指针包装器?

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

我正在尝试将COM接口导入VC++。COM对象来自一个名为IDEA的应用程序,但这并不容易让其他人来帮助我。所以我想,如果有人能给我指示,我将如何为Word做这件事,这将是相当的

IDEA确实有一个.tlb文件,但它似乎不完整。我可以使用python访问COM API,示例如下:

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++包装,不仅暴露了接口,而且如果接口中的东西使用不正确,就会有硬编译错误。