Как использовать VARIANT* с dynamicCall?
Я пытаюсь использовать COM-объект, и у меня возникли проблемы с параметром типа VARIANT*. Я могу использовать функции объекта COM просто отлично, за исключением случаев, когда они имеют параметр этого типа.
Документ, генерируемый generateDocumentation:
QVariantList params =...
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 он тоже не работал.
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();
Надеется, что это кому-то поможет!