首页 > 解决方案 > Qt - ActiveX - 如何处理自定义输出参数?

问题描述

考虑如下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 中的类型不匹配

如何IServerConnectionClientControl


在@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.

标签: c++qtactivexactiveqt

解决方案


通过使用选项--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在这里没用,因为所需接口确实是派生自 的类型(例如IServerConnectionIDispatch,而不是派生自 的生成版本QAxObject


推荐阅读