信号不正确导出时继承自不同的dll [英] signal not correctly exported when inheriting from different dll
问题描述
以下情况:
我在DLL A中有一个类( Parent
),它有一个信号(它是final)。我有一个类( Child
)在DLL B中继承自A.我将这两个DLL导入我的项目。然后我在我的项目中有一个类获得 Child
类的实例,并尝试连接 Child
实例到当前对象。不知怎的这个连接失败。在调试模式下运行整个事情只给我: QObject :: connect:signal在Child
中找不到。检查dumpbin显示信号在DLL A中但不在DLL B中。类 Parent
和类 Child
有正确的导出语句,但不知何故, Child
类的信号不会被导出。这里是整个代码:
a.dll:
class DLLA_SHAREDEXPORT ParentInterface {
public:
〜ParentInterface(){}
virtual void test()= 0;
};
Q_DECLARE_INTERFACE(ParentInterface,ParentInterface)
类DLLA_SHAREDEXPORT父:public QObject,
public ParentInterface {
Q_OBJECT
Q_INTERFACES(ParentInterface)
...
signals:
void test();
}
b.dll:
class DLLB_SHAREDEXPORT Child:public Parent {
Q_OBJECT
...
}
class SomeClass: public QObject {
Q_OBJECT
public:
...
void someFunction(){
Parent * c = getChildObject(); //一些调用获取类Child的对象
QObject :: connect(c,& Parent :: test,
this,& SomeClass :: handle_test);
// QObject :: connect:signal not found in Child
}
}
public slots:
void handle_test(){
// do something
}
}
所以问题似乎是在某处是在DLL B中的一切的正确导出,但我不知道如何做到。
解决方案很抱歉,我无法在任何Windows 10.0上使用MSVC2015重现此问题和Qt 5.7或OS X 10.10。请逐字尝试这个项目,看看它是否适合你。如果是的话,你在做其他错误,并且需要产生一个测试用例并将其编辑到问题中。
项目可以从 https://github.com/KubaO/stackoverflown/tree/master/questions/ sigslot-dll-39149263
sigslot-dll-39149263.pro
TEMPLATE = subdirs
SUBDIRS + = lib1 lib2 main
main.depends + = lib1 lib2
lib2.depends + = lib1
lib1 / lib1.pro
CONFIG + = c ++ 11
TEMPLATE = lib
HEADERS + = lib1.h
win32:DEFINES + = LIB1_EXPORT = __ declspec(dllexport)
lib1 / lib1.h
#ifndef LIB1_H
#define LIB1_H
#include< QObject>
#ifdef WIN32
#ifndef LIB1_EXPORT
#define LIB1_EXPORT __declspec(dllimport)
#endif
#else
#define LIB1_EXPORT
#endif
class LIB1_EXPORT父级:public QObject {
Q_OBJECT
public:
Q_SIGNAL void test();
};
#endif
lib2 / lib2.pro
QT = core
CONFIG + = c ++ 11
TEMPLATE = lib
HEADERS + = lib2.h
win32:DEFINES + = LIB2_EXPORT = __ declspec(dllexport)
win32:CONFIG(debug,release | debug)LIBSUBPATH = / debug
win32:CONFIG(release,release | debug)LIBSUBPATH = / release
LIBS + = -L ../ lib1 $$ LIBSUBPATH -llib1
INCLUDEPATH + = ..
DEPENDPATH + = ..
lib2 / lib2.h
#ifndef LIB2_H
#define LIB2_H
#includelib1 / lib1.h
#ifdef WIN32
#ifndef LIB2_EXPORT
#define LIB2_EXPORT __declspec(dllimport)
#endse
#else
#define LIB2_EXPORT
#endif
class LIB2_EXPORT子代:public Parent {
Q_OBJECT
} ;
#endif
main / main.pro
QT = core
CONFIG + = c ++ 11
TEMPLATE = app
SOURCES + = main.cpp
win32:CONFIG(debug,release | debug)LIBSUBPATH = / debug
win32:CONFIG(release,release | debug)LIBSUBPATH = / release
LIBS + = -L ../ lib1 $$ LIBSUBPATH -llib1 -L ../ lib2 $$ LIBSUBPATH -llib2
INCLUDEPATH + = ..
DEPENDPATH + = ..
main / main.cpp
#includelib1 / lib1.h
#includelib2 / lib2.h
int main(){
int counter = 0;
儿童;
父母* parent =& child;
QObject :: connect(parent,& Parent :: test,[&] {counter ++;});
emit parent-> test();
emit parent-> test();
Q_ASSERT(counter == 2);
}
The following situation: I have a class (
Parent
) in DLL A which has a signal (which is final). I have a class (Child
) in DLL B that inherits from A. I import both DLLs to my project. Then I have a class in my project get an instance of theChild
class and try to connect the signal of theChild
instance to the current object. Somehow this connection fails. Running the whole thing in debug mode only gives me:QObject::connect: signal not found in Child
. Checking the dumpbin shows me that the signal is in DLL A but not in DLL B. Both the classParent
and the classChild
have the proper export statements but somehow the the signal for theChild
class doesn't get exported. Here is the whole thing as code:a.dll:
class DLLA_SHAREDEXPORT ParentInterface{ public: ~ParentInterface(){} virtual void test() = 0; }; Q_DECLARE_INTERFACE(ParentInterface, "ParentInterface") class DLLA_SHAREDEXPORT Parent : public QObject, public ParentInterface{ Q_OBJECT Q_INTERFACES(ParentInterface) ... signals: void test(); }
b.dll:
class DLLB_SHAREDEXPORT Child : public Parent{ Q_OBJECT ... }
class in project:
class SomeClass : public QObject{ Q_OBJECT public: ... void someFunction(){ Parent* c = getChildObject(); //some call to get the Object of class Child QObject::connect(c, &Parent::test, this, &SomeClass::handle_test); //QObject::connect: signal not found in Child } } public slots: void handle_test(){ //do something } }
So the problem seems to be somewhere is the proper export of everything in the DLL B but I can't figure out how to do it. Any help would be appreciated.
解决方案I'm sorry, but I can't reproduce this issue on either Windows 10.0 with MSVC2015 and Qt 5.7 or OS X 10.10. Please try this project verbatim and see if it works for you. If it does, you're doing something else wrong and will need to produce a test case and edit it into the question.
The project is available from: https://github.com/KubaO/stackoverflown/tree/master/questions/sigslot-dll-39149263
sigslot-dll-39149263.pro
TEMPLATE = subdirs SUBDIRS += lib1 lib2 main main.depends += lib1 lib2 lib2.depends += lib1
lib1/lib1.pro
QT = core CONFIG += c++11 TEMPLATE = lib HEADERS += lib1.h win32:DEFINES += LIB1_EXPORT=__declspec(dllexport)
lib1/lib1.h
#ifndef LIB1_H #define LIB1_H #include <QObject> #ifdef WIN32 #ifndef LIB1_EXPORT #define LIB1_EXPORT __declspec(dllimport) #endif #else #define LIB1_EXPORT #endif class LIB1_EXPORT Parent : public QObject { Q_OBJECT public: Q_SIGNAL void test(); }; #endif
lib2/lib2.pro
QT = core CONFIG += c++11 TEMPLATE = lib HEADERS += lib2.h win32:DEFINES += LIB2_EXPORT=__declspec(dllexport) win32:CONFIG(debug,release|debug) LIBSUBPATH=/debug win32:CONFIG(release,release|debug) LIBSUBPATH=/release LIBS += -L../lib1$$LIBSUBPATH -llib1 INCLUDEPATH += .. DEPENDPATH += ..
lib2/lib2.h
#ifndef LIB2_H #define LIB2_H #include "lib1/lib1.h" #ifdef WIN32 #ifndef LIB2_EXPORT #define LIB2_EXPORT __declspec(dllimport) #endif #else #define LIB2_EXPORT #endif class LIB2_EXPORT Child : public Parent { Q_OBJECT }; #endif
main/main.pro
QT = core CONFIG += c++11 TEMPLATE = app SOURCES += main.cpp win32:CONFIG(debug,release|debug) LIBSUBPATH=/debug win32:CONFIG(release,release|debug) LIBSUBPATH=/release LIBS += -L../lib1$$LIBSUBPATH -llib1 -L../lib2$$LIBSUBPATH -llib2 INCLUDEPATH += .. DEPENDPATH += ..
main/main.cpp
#include "lib1/lib1.h" #include "lib2/lib2.h" int main() { int counter = 0; Child child; Parent * parent = &child; QObject::connect(parent, &Parent::test, [&]{ counter++; }); emit parent->test(); emit parent->test(); Q_ASSERT(counter == 2); }
这篇关于信号不正确导出时继承自不同的dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!