Я пытаюсь воспроизвести COM-клиент на С++ без использования MFC. Я могу подключиться к com-интерфейсу и вызвать некоторые методы, требующие простых значений в качестве параметра, но я не могу вызвать метод с указателем в качестве аргумента, функция такова:
short sProdGetCurrentMachineType(short* p_psMachineType)
и в переменной short
, на которую указывает p_psMachineType
, будет сохранено значение результата.
Я пробовал это:
DISPID dispid; //omitted for brevity, i get it from QueryInterface() on the com
VARIANT pVarResult;
EXCEPINFO pExcepInfo;
unsigned int* puArgErr = 0;
DISPPARAMS dispparams{};
VARIANTARG rgvarg[1];
short *p_psMachineType;
rgvarg[0].vt = VT_I2;
rgvarg[0].piVal = p_psMachineType;
dispparams.rgvarg = rgvarg;
dispparams.cArgs = 1;
dispparams.cNamedArgs = 0;
hresult = (*pDisp)->Invoke(
dispid,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparams, &pVarResult, &pExcepInfo, puArgErr
);
но я получаю TYPE_MISMATCH ERROR
..
Вместо этого я увидел, что, используя его в качестве именованного аргумента, я не получаю ошибки при вызове, но значение указателя не заполняется, но я не могу найти ни одного примера указателей, переданных в качестве именованных аргументов.
Кто-нибудь знает, как с этим справиться?
Это сработало! Я думаю, что это единственный вариант, который я не пробовал .. спасибо!
Как вы сами говорите, «в короткой переменной, на которую указывает p_psMachineType, будет храниться значение результата», поэтому вам нужно передать ему действительный указатель на существующий short
.
short psMachineType;
// ...
rgvarg[0].piVal = &psMachineType;
Я по-прежнему получаю сообщение об ошибке TYPE_MISMATCH, а значение psMachineType не заполняется.
Да, VT_I2
обозначает short
не short*
. Я думаю, вы хотите VT_PTR
; изучите документацию, чтобы быть уверенным. (Конечно, значение не заполняется, если вызов завершается сбоем.)
Пробовал, получаю ошибку BAD_VAR_TYPE. Я оставил его как VT_I2, потому что в аналогичном проекте с использованием того же COM-сервера, но с MFC они вызывают InvokeHelper, используя тип VT_I2, и это работает
Как сказал Саймон Мурье, правильным параметром для установки в массиве rgvarg был VT_I2 | VT_BYREF вместо VT_I2
Вы пробовали VT_I2 | VT_BYREF? У меня это работает (в процессе, в той же квартире), но может зависеть от ваших точных деталей реализации (tlb и т. д.). Также убедитесь, что вы правильно инициализировали pExcepInfo и pvarResult (или передали NULL)