Как вернуть из ActiveX-компонента структуру или массив?

Ответить

Код подтверждения
Введите код в точности так, как вы его видите. Регистр символов не имеет значения.

BBCode ВКЛЮЧЁН
[img] ВКЛЮЧЁН
[url] ВКЛЮЧЁН
Смайлики ОТКЛЮЧЕНЫ

Обзор темы
   

Развернуть Обзор темы: Как вернуть из ActiveX-компонента структуру или массив?

Re: Как вернуть из ActiveX-компонента структуру или массив?

Ivan093 » 20 авг 2007, 14:48

Absurd писал(а):А свои методы, которые ты сам и вбил в этот интерфейс у него надеюсь есть =) ?
Хе! Точно есть! :) Смутило то, что при вызове подсказки по свойствам и методам там были только методы Attach, Detach и др. Я и подумал что-то не так :)
А так все работает пока. Спасибо :)

Re: Как вернуть из ActiveX-компонента структуру или массив?

Absurd » 20 авг 2007, 14:44

Ivan093 писал(а):Не совсем понятно как получить доступ и выполнить методы интерфейса.
Интерфейс получаю так:

Код: Выделить всё

    CComPtr<IUnknown> unk = ObjList.punkVal; //ObjList объект, возвращаемый 1С
    CComPtr<IxUserObjList> ptr;
    long er = unk->QueryInterface(&ptr); //er = 0, значит успешно получили интерфейс
Что теперь делать с ptr? Invoke у него нету.
А свои методы, которые ты сам и вбил в этот интерфейс у него надеюсь есть =) ?

Re: Как вернуть из ActiveX-компонента структуру или массив?

Ivan093 » 20 авг 2007, 14:40

Не совсем понятно как получить доступ и выполнить методы интерфейса.
Интерфейс получаю так:

Код: Выделить всё

    CComPtr<IUnknown> unk = ObjList.punkVal; //ObjList объект, возвращаемый 1С
    CComPtr<IxUserObjList> ptr;
    long er = unk->QueryInterface(&ptr); //er = 0, значит успешно получили интерфейс
Что теперь делать с ptr? Invoke у него нету.

Re: Как вернуть из ActiveX-компонента структуру или массив?

Absurd » 20 авг 2007, 11:00

Ivan093 писал(а): В других языках могут быть предусмотрены специальные средства, которые скрывают от вас все эти детали. Например, в Java имеется встроенный механизм сборки мусора, который сам занимается подсчетом ссылок. Кроме того, один из механизмов Java был позаимствован Microsoft для реализации QueryInterface — речь идет о преобразовании типов. У программиста появляется возможность получить новый интерфейс в виде класса, преобразовав его к нужному типу; возвращаемое значение NULL свидетельствует о том, что интерфейс не поддерживается данным объектом.

Вот интересует последнее предложение, т.е. как из интерфейса получить класс?
Кто-нибудь делал это?
Брехня. В Java есть аналог стандартного С++ dynamic_cast<>. Т.е при включенном RTTI в С++ можно сделать так

Код: Выделить всё

std::auto_ptr<SomeFactory::ProductType> p(SomeFactory::Instance().Create());
MyInterface* mif = dynamic_cast<MyInterface*>(p.get());
if (mif != 0) {
   ...
   mif->mifMethod(...);
   ...
} else {
   throw std::logic_error("Factory has returned unsupported object");
}
В Java 1.4 полный аналог этого выглядит так:

Код: Выделить всё

final Object o = SomeFactory.getInstance().create();
if (o instanceof MyInterface) {
  final MyInterface mif = (MyInterface)o;
  ...
  mif.mifMethod(...);
  ...
} else {
  throw new RuntimeException("Factory has returned unsupported object");
}
Подсчета ссылок в Java нет, т.к это не годится для Java. Для внутреннего использования в изолированных компонентах C/C++ использовать его можно, для гетерогенных сред - можно только если аффтар гетерогенной среды типа COM гхм... недальновиден.
Вот интересует последнее предложение, т.е. как из интерфейса получить класс?
CComPtr<IUnknown> o(in_param);
CComPtr<IMyInterface> mif;
o.QueryInterface(mif);

Как-то так: CComPtr берет всю химию по трансформации IUnknown->IMyInterface на себя.

Re: Как вернуть из ActiveX-компонента структуру или массив?

Ivan093 » 20 авг 2007, 10:19

Up!
Всем добрый день!
Наконец я вернулся из отпуска и надо снова вникать в работу :)
Что касается последнего вопроса, то он пока не решен.
Прочитал тут в одной книжке по ActiveX вот что:

В других языках могут быть предусмотрены специальные средства, которые скрывают от вас все эти детали. Например, в Java имеется встроенный механизм сборки мусора, который сам занимается подсчетом ссылок. Кроме того, один из механизмов Java был позаимствован Microsoft для реализации QueryInterface — речь идет о преобразовании типов. У программиста появляется возможность получить новый интерфейс в виде класса, преобразовав его к нужному типу; возвращаемое значение NULL свидетельствует о том, что интерфейс не поддерживается данным объектом.

Вот интересует последнее предложение, т.е. как из интерфейса получить класс?
Кто-нибудь делал это?

Re: Как вернуть из ActiveX-компонента структуру или массив?

Absurd » 26 июл 2007, 11:58

Ivan093 писал(а):Т.е. только через вызовы методом интерфейса можно получить доступ к данным?
Даже несмотря на то, что объект создан в том же коде, в котором его и надо разобрать, просто заполнен он внешней программой (1С)?
Через QueryInterface запроси нужный интерфейс и все. IDispatch тоже наследуется от IUnknown и метод IUnknown->QueryInterface() соответственно имеет.

Re: Как вернуть из ActiveX-компонента структуру или массив?

Romeo » 24 июл 2007, 14:00

Кстати. Этот объект случайно не имплементирует некий кастомный интерфейс, благодаря которому 1C может его заполнить. Если имплементирует, да к тому же этот кастомный интерфейс подразумевает не только запись, но и чтение пропертей, то просто опроси этот интерфейс через QueryInterface и пользуйся им наздоровье.

Если же кастомного интерфейса нет, и 1C сама использует только Dispatch для записи данных в объект, то, боюсь, друго способа получить эти данные просто нет.

Re: Как вернуть из ActiveX-компонента структуру или массив?

Ivan093 » 24 июл 2007, 10:33

Romeo писал(а):Если известен IDispatch, то можно получить список методов и пропертей, пользуясь GetTypeInfoCount и GetTypeInfo, а затем вызвать эти методы или проперти, используя Invoke.
Т.е. только через вызовы методом интерфейса можно получить доступ к данным?
Даже несмотря на то, что объект создан в том же коде, в котором его и надо разобрать, просто заполнен он внешней программой (1С)?

Re: Как вернуть из ActiveX-компонента структуру или массив?

Romeo » 23 июл 2007, 15:37

Если известен IDispatch, то можно получить список методов и пропертей, пользуясь GetTypeInfoCount и GetTypeInfo, а затем вызвать эти методы или проперти, используя Invoke.

Re: Как вернуть из ActiveX-компонента структуру или массив?

Romeo » 23 июл 2007, 15:34

Посмотри в дебаге поле ObjList.vt. Скорее всего это VT_DISPATCH, вотзможно объединённый с VT_BYREF. Если VT_BYREF присутствует, то используй ObjList.byref и интерпритируй его, как ссылку на то место, где лежит IDispath поинтер. Если VT_BYREF не выставлен, то используй ObjList.punkVal, интерпритируя его, как IDispath поинтер.

Вернуться к началу