• 20311阅读
  • 10回复

dumpcpp生成的h和cpp文件的问题 [复制链接]

上一主题 下一主题
离线sbtree
 
只看楼主 倒序阅读 楼主  发表于: 2010-01-13
— 本帖被 XChinux 执行加亮操作(2010-09-02) —
手头上只有dll文件,所以用dumpcpp工具生成了相应的h和cpp文件,可是发现一个问题,自动为dll生成的函数没了返回值,其函数的实现是通过qt_metacall函数改写的,例如
inline void S7ProSim::ReadOutputImage(int StartIndex, int ElementsToRead, S7PROSIMLib::__MIDL___MIDL_itf_S7wspsmx_0000_0002 DataType, QVariant& pData)
{
    void *_a[] = {0, (void*)&StartIndex, (void*)&ElementsToRead, (void*)&DataType, (void*)&pData};
    qt_metacall(QMetaObject::InvokeMetaMethod, 24, _a);
}
现在我该怎样重新得到返回值呢?变量_a中的第一个元素看起来像是用来保存返回值的,可以通过它得到吗?另外在文档中根本查不到qt_metacall函数的相关信息,有这方面经验的达人能给指点一下吗?
windows 7 + VC++2008 + Qt4.5.2
离线dbzhang800

只看该作者 1楼 发表于: 2010-01-13
dumpcpp 是 ActiveQt 模块中的tool吧?

你或许需要先找些 COM 和 ActiveX 的资料看看,然后再回到Qt
离线sbtree
只看该作者 2楼 发表于: 2010-01-13
dumpcpp工具的主要功能就是利用二进制库文件或者tlb文件生成相关的c++头文件和cpp文件,并利用QAxObject类重新封装了原来的组件,从而简化原来组件的复杂接口,并借此能够利用qt的meta系统,也就能进一步实现信号与槽的功能,与qt完美结合。我现在的问题不在于对com组件系统的了解,诸如IDispatch等接口问题,而是meta,正如上面提到的qt_metacall这样的函数,怎样去认识和应用它,因为文档中没有相关的信息
windows 7 + VC++2008 + Qt4.5.2
离线dbzhang800

只看该作者 3楼 发表于: 2010-01-14
手头上只有dll文件,所以用dumpcpp工具生成了相应的h和cpp文件,可是发现一个问题,自动为dll生成的函数没了返回值,其函数的实现是通过qt_metacall函数改写的,例如
inline void S7ProSim::ReadOutputImage(int StartIndex, int ElementsToRead, S7PROSIMLib::__MIDL___MIDL_itf_S7wspsmx_0000_0002 DataType, QVariant& pData)
{
    void *_a[] = {0, (void*)&StartIndex, (void*)&ElementsToRead, (void*)&DataType, (void*)&pData};
    qt_metacall(QMetaObject::InvokeMetaMethod, 24, _a);
}
现在我该怎样重新得到返回值呢?变量_a中的第一个元素看起来像是用来保存返回值的,可以通过它得到吗?另外在文档中根本查不到qt_metacall函数的相关信息,有这方面经验的达人能给指点一下吗?

引用第2楼sbtree于2010-01-13 21:01发表的  :
dumpcpp工具的主要功能就是利用二进制库文件或者tlb文件生成相关的c++头文件和cpp文件,并利用QAxObject类重新封装了原来的组件,从而简化原来组件的复杂接口,并借此能够利用qt的meta系统,也就能进一步实现信号与槽的功能,与qt完美结合。我现在的问题不在于对com组件系统的了解,诸如IDispatch等接口问题,而是meta,正如上面提到的qt_metacall这样的函数,怎样去认识和应用它,因为文档中没有相关的信息


你的 S7ProSim 是 QAxObject 的派生类吧?
那么就可以考虑看看 QAxObject 的实现了(qaxobject.cpp)

  1. int QAxObject::qt_metacall(QMetaObject::Call call, int id, void **v)
  2. {
  3.     id = QObject::qt_metacall(call, id, v);
  4.     if (id < 0)
  5.         return id;
  6.     return QAxBase::qt_metacall(call, id, v);
  7. }


QAxObject 继承自 QObject 和 QAxBase.

对于 QObject::qt_metacall 我们或许不陌生,定义类时添加的 Q_OBJECT 宏就包含其声明,其实现在moc自动生成的 moc_...h 文件内。

对于 QAxBase::qt_metacall ,可以继续看 QAxBase的实现
  1. int QAxBase::qt_metacall(QMetaObject::Call call, int id, void **v)
  2. {
  3.     const QMetaObject *mo = metaObject();
  4.     if (isNull() && mo->property(id + mo->propertyOffset()).name() != QByteArray("control")) {
  5.         qWarning("QAxBase::qt_metacall: Object is not initialized, or initialization failed");
  6.         return id;
  7.     }
  8.     switch(call) {
  9.     case QMetaObject::InvokeMetaMethod:
  10.         switch (mo->method(id + mo->methodOffset()).methodType()) {
  11.         case QMetaMethod::Signal:
  12.             QMetaObject::activate(qObject(), mo, id, v);
  13.             id -= mo->methodCount();
  14.             break;
  15.         case QMetaMethod::Method:
  16.         case QMetaMethod::Slot:
  17.             id = internalInvoke(call, id, v);
  18.             break;
  19.         default:
  20.             break;
  21.         }
  22.         break;
  23. ...
  24.     default:
  25.         break;
  26.     }
  27.     Q_ASSERT(id < 0);
  28.     return id;
  29. }


慢慢看下去,最后就是COM中熟悉的 IDispach 接口的Invoke函数

  1. int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v)
  2. {
  3.     Q_ASSERT(call == QMetaObject::InvokeMetaMethod);
  4.     Q_UNUSED(call);
  5.     // get the IDispatch
  6.     IDispatch *disp = d->dispatch();
  7. ....
  8.     DISPID dispid = d->metaObject()->dispIDofName(slotname, disp);
  9.     Q_ASSERT(d->metaobj);
  10.     if (dispid == DISPID_UNKNOWN && slotname.toLower().startsWith("set")) {
  11.         // see if we are calling a property set function as a slot
  12.         slotname = slotname.right(slotname.length() - 3);
  13.         dispid = d->metaobj->dispIDofName(slotname, disp);
  14.         isProperty = true;
  15.     }
  16.     if (dispid == DISPID_UNKNOWN)
  17.         return index;
  18.     // slot found, so everthing that goes wrong now should not bother the caller
  19.     index -= mo->methodCount();
  20.     // setup the parame
  21.     DISPPARAMS params;
  22.     DISPID dispidNamed = DISPID_PROPERTYPUT;
  23.     params.cArgs = d->metaobj->numParameter(signature);
  24.     params.cNamedArgs = isProperty ? 1 : 0;
  25.     params.rgdispidNamedArgs = isProperty ? &dispidNamed : 0;
  26.     params.rgvarg = 0;
  27.     VARIANTARG static_rgvarg[QAX_NUM_PARAMS];
  28.     if (params.cArgs) {
  29.         if (params.cArgs <= QAX_NUM_PARAMS)
  30.             params.rgvarg = static_rgvarg;
  31.         else
  32.             params.rgvarg = new VARIANTARG[params.cArgs];
  33.     }
  34.     int p;
  35.     for (p = 0; p < (int)params.cArgs; ++p) {
  36.         bool out;
  37.         QByteArray type = d->metaobj->paramType(signature, p, &out);
  38.         QVariant::Type vt = QVariant::nameToType(type);
  39.         QVariant qvar;
  40.         if (vt != QVariant::UserType)
  41.             qvar = QVariant(vt, v[p + 1]);
  42.         if (!qvar.isValid()) {
  43.             if (type == "IDispatch*")
  44.                 qVariantSetValue(qvar, *(IDispatch**)v[p+1]);
  45.             else if (type == "IUnknown*")
  46.                 qVariantSetValue(qvar, *(IUnknown**)v[p+1]);
  47.             else if (type == "QVariant")
  48.                 qvar = *(QVariant*)v[p + 1];
  49.             else if (mo->indexOfEnumerator(type) != -1)
  50.                 qvar = *(int*)v[p + 1];
  51.             else
  52.                 qvar = QVariant(QMetaType::type(type), v[p + 1]);
  53.         }
  54.         QVariantToVARIANT(qvar, params.rgvarg[params.cArgs - p - 1], type, out);
  55.     }
  56.     // call the method
  57.     VARIANT ret;
  58.     VariantInit(&ret);
  59.     UINT argerr = 0;
  60.     HRESULT hres = E_FAIL;
  61.     EXCEPINFO excepinfo;
  62.     memset(&excepinfo, 0, sizeof(excepinfo));
  63.     WORD wFlags = isProperty ? DISPATCH_PROPERTYPUT : DISPATCH_METHOD | DISPATCH_PROPERTYGET;
  64.     hres = disp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, wFlags, &params, &ret, &excepinfo, &argerr);
  65.     // get return value
  66.     if (hres == S_OK && ret.vt != VT_EMPTY)
  67.         QVariantToVoidStar(VARIANTToQVariant(ret, slot.typeName()), v[0], slot.typeName());
  68.     // update out parameters
  69.     for (p = 0; p < (int)params.cArgs; ++p) {
  70.         bool out;
  71.         QByteArray ptype = d->metaobj->paramType(signature, p, &out);
  72.         if (out)
  73.             QVariantToVoidStar(VARIANTToQVariant(params.rgvarg[params.cArgs - p - 1], ptype), v[p+1], ptype);
  74.     }
  75.     // clean up
  76.     for (p = 0; p < (int)params.cArgs; ++p)
  77.         clearVARIANT(params.rgvarg+p);
  78.     if (params.rgvarg != static_rgvarg)
  79.         delete [] params.rgvarg;
  80.     checkHRESULT(hres, &excepinfo, this, QString::fromLatin1(slotname), params.cArgs-argerr-1);
  81.     return index;
  82. }
离线sbtree
只看该作者 4楼 发表于: 2010-01-14
多谢dbzhang800的耐心回复,学习了
   // get return value
    if (hres == S_OK && ret.vt != VT_EMPTY)
        QVariantToVoidStar(VARIANTToQVariant(ret, slot.typeName()), v[0], slot.typeName());
这个返回值对我很有用,因为我的问题就是得不到返回值。
windows 7 + VC++2008 + Qt4.5.2
离线lxkjlzz
只看该作者 5楼 发表于: 2010-08-30
dumpcpp生成的h和cpp文件的问题

有QAxObject *的指针,但参数要求是Idispatch *怎么传啊
weigang1982@126.com
离线辣手中将
只看该作者 6楼 发表于: 2013-01-24
有生成.h  .cpp文件的步骤么 求解!!
离线行潇

只看该作者 7楼 发表于: 2013-01-29
你好,我在使用dumpcpp生成h文件和cpp文件,在程序中调用其中的com函数是出现以下出错:

[size=; font-size: 10pt,10pt]QAxBase::qt_metacall: Object is not initialized, or initialization failed
[size=; font-size: 10pt,10pt]QAxBase::qt_metacall: Object is not initialized, or initialization failed
[size=; font-size: 10pt,10pt]QAxBase: Error calling IDispatch member Start: Unknown error
[size=; font-size: 10pt,10pt]QAxBase: Error calling IDispatch member Send: Unknown error
[size=; font-size: 10pt,10pt]请问,该怎么解决呢?
离线john607995

只看该作者 8楼 发表于: 2013-02-28
请问,最后这个返回值是怎么获取的
离线john607995

只看该作者 9楼 发表于: 2013-02-28
回 3楼(dbzhang800) 的帖子
请问,这个返回值是怎么获取的,感谢了。
离线paresly

只看该作者 10楼 发表于: 2016-01-19
问一下,这个问题后来怎么解决的,小弟目前也遇到这样的情况了
快速回复
限100 字节
 
上一个 下一个