考虑下面定义的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
。
通过使用选项--compat
Options ... --compat Treat all coclass parameters as IDispatch.
dumpcpp
生成如下波纹源:
class ClientControl : public QAxWidget
{
public:
...
inline void GetServerConnection(IDispatch** ppServerConnection);
...
};
[Q可以处理IDispatch
的类型。
Qt
使用QVariant
存储参数并将其传递到下面的VARIANT
,它专门处理IUnknown
和IDispatch
。 Q_DECLARE_METATYPE
在这里是无用的,因为这样的论点是所需接口确实是从IServerConnection
派生的类型(例如IDispatch
),而不是从QAxObject
派生的生成版本。