Как использовать VARIANT* с dynamicCall?

Я пытаюсь использовать COM-объект, и у меня проблема с типом параметра VARIANT*. Я могу прекрасно использовать функции COM-объекта, за исключением случаев, когда у них есть параметр этого типа.

Документ, созданный generateDocumentation:

Параметры QVariantList = ...

object->dynamicCall("GetRanges(int,int,int&, QVariant&)", params);

Согласно документу, предоставленному с COM-объектом, параметры должны иметь тип LONG, LONG, LONG* и VARIANT*, и уточняется, что VARIANT* является указателем на VARIANT, содержащий массив BSTR.

Обычно я должен иметь возможность получить третий и четвертый параметры (типа LONG* и VARIANT*), и их значения не используются функцией.

Вот мой код (a и b предварительно инициализированы):

QStringList sl;
QVariantList params;
int i = -1;
params << QVariant (a);
params << QVariant (b);
params << QVariant (i);
params << QVariant (sl);

comobject->dynamicCall("GetRanges(int,int,int&,QVariant&)",params);
sl = params[3].toStringList();
i = param[2].toInt();

Теперь с этим кодом все, что я получаю, это ошибка QAxBase: Ошибка при вызове члена IDispatch GetRanges: Неизвестная ошибка, что не очень полезно.

Я попытался изменить некоторые вещи, и мне удалось продвинуться (вроде) с помощью этого кода:

QStringList sl;
QVariant v = qVariantFromValue(sl);
QVariantList params;
int i = -1;
params << QVariant (a);
params << QVariant (b);
params << QVariant (i);
params << qVariantFromValue((void*)&v);

comobject->dynamicCall("GetRanges(int,int,int&,QVariant&)",params);
sl = params[3].toStringList();
i = param[2].toInt();

Это избавляет от ошибки, и значение i в конце правильное, но sl по-прежнему пуст. И я знаю, что этого не должно быть, потому что у меня есть образец демо на C#, который работает правильно.

Так что, если у кого-то есть идея, как заставить его работать...

В противном случае я немного осмотрелся и увидел, что также можно запросить интерфейс и использовать его напрямую, но я мало что понял и не уверен, что это решит мои проблемы.

Я работаю на 64-битной платформе Windows7 и использую msvc2012 в качестве компилятора. Сейчас я использую Qt 5.1.0, но и в 5.0.2 это не сработало.


person Tuirenen    schedule 11.07.2013    source источник


Ответы (1)


Я думаю, вы действительно не можете сделать это с dynamicCall. Наконец-то я нашел, как это сделать. Это было проще, чем я думал. С установкой Qt поставляется инструмент под названием dumpcpp. Полный путь для меня был C:\Qt\Qt5.1.0x86\5.1.0\msvc2012\bin\dumpcpp.exe (очевидно, зависит от настроек). Вы можете просто добавить папку bin в свой путь, чтобы упростить ее использование. Затем я зашел в папку своего проекта и выполнил эту команду:

dumpcpp -nometaobject {00062FFF-0000-0000-C000-000000000046} (CLSID только для примера, а не тот, который я использовал)

Он создает файл заголовка, вы можете включить его в файл, в котором вы пытаетесь использовать COM-объект.

В этом файле в моем случае было два класса (IClassMeasurement и ClassMeasurement) в пространстве имен (MeasurementLib). Опять же, имена не настоящие.

В исходном файле проекта вы можете вызвать нужную функцию следующим образом:

MeasurementLib::ClassMeasurement test; //Do not use IClassMeasurement, you only get write access violations
QVariant rangesVar;
int p1 = 0;
int p2 = 0;
int p3 = 0;
test.getRanges(p1,p2,p3,ranges);
QStringList ranges = ranges.toStringList();

Надеется, что это поможет кому-то!

person Tuirenen    schedule 14.08.2013
comment
Я попробовал этот метод. Это работает для строк, но не для вариантов, которые должны быть заполнены элементом управления. Я получаю то же сообщение об ошибке, что и вы. Ошибка при вызове члена IDispatch GetRanges: неизвестная ошибка - person Steve Kolokowsky; 29.03.2016