Как я могу получить VC ++ для автоматического создания оболочек тонких интеллектуальных указателей для COM-объекта? - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь импортировать интерфейс COM в VC ++. COM-объект взят из приложения под названием IDEA, но так как это не очень легко достать, чтобы другие помогли мне. Поэтому я полагаю, что если бы кто-то мог дать мне инструкции относительно того, как я это сделаю для Word, это было бы эквивалентно.

У IDEA есть файл .tlb, но может показаться, что он неполный. Я могу получить доступ к COM API, используя python, например, что-то вроде этого:

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

Используя файл .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.application), я подумал, что это можно было бы использовать. Оглядываясь вокруг, я не могу найти ссылку на это, используя #import. Я видел, как он используется с CLSIDFromProgID, но это очень ручной механизм. COM SMARTPTR были бы гораздо предпочтительнее.

Возможно ли это вообще сделать с VC ++?

1 Ответ

0 голосов
/ 23 января 2019

Возможно OpenDatabase возвращает IDispatch, но интерфейс, содержащий TableDef, все еще определен в TLB. В этом случае вам нужно уменьшить IDispatch до I-something-containing-TableDef-method.

Используйте QueryInterface вызов для получения производного интерфейса от IDispatch, а не от приведения C или C ++, например static_cast.

В противном случае вам нужно будет использовать IDispatch::Invoke. Лучшая помощь для вас - CComPtr<IDispatch> от ATL, эта специализация шаблона имеет помощников Invoke, так что вы можете сделать что-то вроде этого:

CComPtr<IDispatch> p;
p = db;
CComVairant result;
p.Invoke("TableDef", &result);

Или используйте IDispatch :: Invoke как есть.

Python всегда опирается на IDispatch::Invoke и не использует статические интерфейсы, поэтому он не сталкивается с этой проблемой.

...