Странные COM DLL

147
21 февраля 2019, 05:20

Появилась задача прицепить к программе на с++/qt драйверы торгового оборудования для 1с8.3. Казалось бы проблем быть не должно т.к. технология внешних компонент 1С документирована очень хорошо, как и требования к драйверам (хотя это совершенно не важно). С native компонентами проблем не возникло - там все однозначно и прямолинейно.

А вот с COM какой то бардак! Для примера я взял драйверы для ККМ из поставки 1С8.3. Они поставляются в zip архивах в виде dll/so и файлов manifest.xml и info.xml. Проблема в том, что все библиотеки, созданные по технологии COM разные! Только одна dll соответствует спецификации! Остальные реализуют расширения языка 1С как попало, но тем не менее, каким то волшебным образом, в 1С они все прекрасно работают. Я подозреваю это происходит потому, что 1С это очень древняя платформа и внешние компоненты COM пишут как попало, а 1С вынуждена весь этот зоопарк поддерживать. В принципе реализовать все костыли, применяемые 1С можно без особого труда, но выяснилась очень неприятная вещь - некоторые DLL с COM объектами не содержат в себе манифеста с описанием интерфейсов COM.

Например Spark115FComp.dll это компонента, созданная по всем правилам - в ней 4 интерфейса, 3 и которых требует технология. Это единственная COM библиотека, сделанная по стандарту.

Библиотека smDrvFR1CLib20.dll реализует 2 интерфейса - один для ДТО 2.0, а второй для ДТО 2.2. Интерфейсов которые должны быть по технологии нет. В требованиях ДТО это вроде допустимо.

Библиотека IskraKKTLib.dll (AddIn.IskraKKT) вообще за гранью добра и зла! Я не могу сгенерировать TLB для этой компоненты. OleView выдет ошибку "LoadTypeLib(\IskraKKTLib.dll) failed. Error loading type library/DLL. TYPE_E_CANTLOADLIBRARY ($80029C4A)". Получить ITypeInfo прямо из программа тоже не могу - получаю пустой указатель.

CoInitializeEx(nullptr, COINIT_MULTITHREADED);
ax = new QAxObject("AddIn.IskraKKT");
ITypeInfo *typeInfo = nullptr;
IDispatch *dispatch = nullptr;
ax->queryInterface(IID_IDispatch, reinterpret_cast<void **>(&dispatch));
if (dispatch){
    dispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &typeInfo);
}

В компоненте просто нет информации ни о доступных интерфейсах ни о доступных методах. Я в тупике. Предположим, что все COM-драйверы возвращают интерфейс по умолчанию, реализующий нужные функции. Тогда как мне вызывать функции этого интерфейса? На сколько я понял dynamicCall использует ITypeInfo для вызова произвольной функции, поэтому использовать его не получится. Значит нужно сгенерировать описание интерфейса. Но как это сделать? Буду очень благодарен за помощь. На всякий случай прилагаю dll с COM драйверами. https://yadi.sk/d/AGhuibb-UbVYpQ

Answer 1

Одним из вариантов решения может быть подключение обычной dll (не для 1С) см http://www.iskra-cto.ru/%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8/

READ ALSO
Custom deleter. Smart pointer std::unique_ptr();

Custom deleter. Smart pointer std::unique_ptr();

Не очень могу понять, что происходит в этом кодеНужно создать свой deleter, для умного указателя

140
Как в cmake подключить библиотеку libpqxx?

Как в cmake подключить библиотеку libpqxx?

Как в cmake подключить библиотеку libpqxx?

180
Аналог параллельного цикла из openmp

Аналог параллельного цикла из openmp

Есть ли аналог для #pragma omp parallel for из openmp в текущем c++ стандарте?

155
QT MYSQL QThread

QT MYSQL QThread

У меня есть два класса: checkMessage унаследованный от QThread и основной класс-форма mainwindow унаследованный от QWidgetВ первом классе раз в несколько секунд...

132