Qt - ActiveX - Как обработать пользовательский выходной параметр? - PullRequest
0 голосов
/ 18 января 2020

Учитывая idl, определенный как ниже:

interface IServerConnection : IDispatch {
    [id(1), helpstring("method IsConnected")] HRESULT IsConnected([out] BOOL* pVal);
};

interface IClientControl : IDispatch {
    [id(1), helpstring("method GetServerConnection")] HRESULT GetServerConnection([out] IServerConnection** ppServerConnection);
};

dumpcpp генерирует код как ниже:

class IServerConnection : public QAxObject
{
public:
    ...
    inline void IsConnected(int& pVal);
    ...
};


class ClientControl : public QAxWidget
{
public:
    ...

    ClientControl (IClientControl *iface)
    : QAxWidget()
    {
        initializeFrom(iface);
        delete iface;
    }

    inline void GetServerConnection(IServerConnection** ppServerConnection);
    ...
};

Возвращает несоответствие типов, если я вызываю ClientControl::GetServerConnection .

QAxBase: Ошибка при вызове члена IDispatch GetServerConnection: Несоответствие типов в параметре 0

Как получить IServerConnection из ClientControl?


С предложением @Remy Lebeau idl изменилось на:

interface IServerConnection : IDispatch {
    [id(1), helpstring("method IsConnected")] HRESULT IsConnected([out] BOOL* pVal);
};

interface IClientControl : IDispatch {
    [id(1), helpstring("method GetServerConnection")] HRESULT GetServerConnection([out, retval] IServerConnection** ppServerConnection);
};

Затем источник, сгенерированный dumpcpp:

class ClientControl : public QAxWidget
{
public:
    ...
    inline IServerConnection* GetServerConnection();
    ...
};

Вызвав GetServerConnection как:

ClientControl ctrl;
auto conn = ctrl.GetServerConnection();

Он выводит:

QVariantToVARIANT: out-parameter not supported for "subtype".
QAxBase: Error calling IDispatch member GetServerConnection: Member not found

Изменение исходного кода или реализации за idl невозможно. Я не могу изменить интерфейс на тип возвращаемого значения, и это другой вопрос.

Это скорее проблема Qt, чем idl.

1 Ответ

1 голос
/ 18 января 2020

Используя опцию --compat

Options
  ...
  --compat        Treat all coclass parameters as IDispatch.

dumpcpp генерировать источник, как показано ниже:

class ClientControl : public QAxWidget
{
public:
    ...
    inline void GetServerConnection(IDispatch** ppServerConnection);
    ...
};

Тип IDispatch может быть обработан по Qt.

Qt используйте QVariant для хранения и передачи аргументов в VARIANT, он обрабатывает IUnknown и IDispatch специально. Q_DECLARE_METATYPE здесь бесполезен, поскольку аргумент, что требуемый интерфейс действительно является типом (например, IServerConnection), полученным из IDispatch, а не сгенерированной версией, которая получена из QAxObject.

...