-1

Considering an idl defined like bellow:

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);
};

The dumpcpp generate code like bellow:

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);
    ...
};

It returns type mismatch if I direct call ClientControl::GetServerConnection.

QAxBase: Error calling IDispatch member GetServerConnection: Type mismatch in parameter 0

How to get IServerConnection from the ClientControl?


With suggestion by @Remy Lebeau the idl changed to:

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);
};

Then the source generated by dumpcpp:

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

By calling GetServerConnection like:

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

It outputs:

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

Changing the source code or implementation behind the idl is impossible. I can't change the interface to a return type, and that's another question.

It's more like a Qt problem rather than idl.

Xiaofeng
  • 532
  • 7
  • 22
  • Please show your actual code that is getting the type mismatch error when trying to "direct call `ClientControl::GetServerConnection`". And FYI, in both methods shown, the `[out]` parameter should be marked as `[out, retval]` instead. – Remy Lebeau Jan 18 '20 at 17:29
  • ``ClientControl::GetServerConnection`` is a member function, what do you mean by the actual code? I'm not familiar with `idl`, and it's provided by a sdk, I will try to find out how to use it. Thanks. – Xiaofeng Jan 19 '20 at 01:18
  • the `[out]` parameter of `IsConnected()` should also be `[out, retval]` – Remy Lebeau Jan 19 '20 at 04:41
  • That is unused, and should not make any difference to my question. – Xiaofeng Jan 19 '20 at 06:04

1 Answers1

1

By using option --compat

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

dumpcpp generate source like bellow:

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

The type of IDispatch can be handled by Qt.

Qt use QVariant to store and transfer arguments to VARIANT underneath, it handles IUnknown and IDispatch specially. Q_DECLARE_METATYPE is useless here, as the argument that the interface required is indeed a type(e.g. IServerConnection) derived from IDispatch, not the generated version, which is derived from QAxObject.

Xiaofeng
  • 532
  • 7
  • 22