When calling the Shared Libraries (DLL) created by QT6, the main program will crash
-
@pedisChen said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
My dll file was built with QT6, and then I created another project with QT6 and tried to call it
You don't "call" DLLs, you link them.
Then I added the generated file to my project directory, but it's still the same.
This is not what @J-Hilk was talking about.
If you export/deploy your qt widget library, you need to ship it with all the other libs your library needs.@pedisChen said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
I think it is because the dll lacks of an QT event loop mechanism. so I added an init function in dll,and need to call the init function first , defined like this:
QCoreApplication a(argc, argv); return a.exec();
A library doesn't necessarily need that.
A Qt library can be aQWidget
, just a colletion of functions or something else...
None of these need their ownQCoreApplication
, when used in other Qt apps.
(They do in general in order to work, but at least not their own. The main loop from the app to which your library is linked to, is fine).See this example:
If you look at the code, there is nomain.cpp
or additionalQApplication
involved.
But one is needed to use the library widget in your main app.Edit:
@pedisChen said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
This worked, but it would always block the main program. Then I planned to use QThread to create a new process in the dll to run a.exec(), but it failed and the new process task could not run.I dont know why...
In what way do you use your library? Or how do you intend to use it in some application?
How does your library work? Do you export a single widget, which usesQTCPSocket
in your library?Another observation:
If you don't have an event loop in your main application (when no Qt involved in main app), you obviously can't create a
QThread
which then should host theQApplication
instance...QThread
is a wrapper forstd::thread
and is aQObject
itself. Therefore it also needs aQApplication
to work properly.
Use a plainstd::thread
instead. -
@Pl45m4 said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
If you export/deploy your qt widget library, you need to ship it with all the other libs your library needs.
Because I was linking the dll file use another qt project
so I copied all the files(ship it all?) generated by windeployqt6.exe to the project dlll linking dirI use QTCPSocket in the dll for TCP connection, and then the main program crashes for unknown reasons
dll code like this:
A.cppuint8_t mySocket::Connect() { if(this->ip.isEmpty()) return CONNECT_ADDR_FAIL; if(this->port == 0) return CONNECT_ADDR_FAIL; /* device connect */ if(_s.state() != QAbstractSocket::ConnectedState) _s.connectToHost(this->ip, this->port); return 0; }
B.cpp
uint8_t tcp_connect(void *mySocketHandle) { return ((mySockeDLL_t)mySocketHandle)->Connect(); }
B.h
#ifdef __cplusplus extern "C" { #endif //__cplusplus .... uint8_t DLL_EXPORT tcp_connect(void * mySocketHandle); ..... #ifdef __cplusplus } #endif //__cplusplus
in another project, use QLibrary to link dlls
code like thisQLibrary library("myDLL"); if (library.load()) { ...... typedef uint8_t (* tcp_connect)(void * mySocketHandle); tcp_connect f2 = (tcp_connect)library.resolve("tcp_connect"); f2(mySocketHandle); ....... } library.unload();
after run .exe
23:00:52: D:\Code\QT_PROJECT\libraryTest\importDLL\build-importDLL-Desktop_Qt_6_5_3_MinGW_64_bit-Release\release\importDLL.exe crashed. -
Apart from wtf are you doing here:
f2(mySocketHandle);
Does mySocketHandle really contains the pointer to your class instance?
-
@Christian-Ehrlicher yes,it is a pointer,maybe the var name is confusing,but the tcp socket connected successfully and after some second the main program crash down
-
tbh - wrapping a c++ class in a c api is...
Why all this strange stuff instead simply linking against the library like everyone else is doing it?
-
@Christian-Ehrlicher because Idont know how to use Qlibrary to resolve a class object and I want it to be compatible for use in code written in C.
-
because Idont know how to use Qlibrary to resolve a class object
https://doc.qt.io/qt-6/plugins-howto.html#the-low-level-api-extending-qt-applications
and I want it to be compatible for use in code written in C.
Since you need a running Q(Core)Application somewhere this will not work out.
-
@Christian-Ehrlicher said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
Since you need a running Q(Core)Application somewhere this will not work out.
Can I still use QTcpSocket for TCP communication? I want the generated DLL to be linkable by C code.
-
@Christian-Ehrlicher Can I create a init function in dll running in another thread that running QCoreApplication?
-
@pedisChen said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
Can I still use QTcpSocket for TCP communication? I want the generated DLL to be linkable by C code.
You need a running Q(Core)Application as we already told you.
Can I create a init function in dll running in another thread that running QCoreApplication?
You can, but you will get in trouble when the objects are not in that thread. It's not worth the trouble.
-
@Christian-Ehrlicher said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
You can, but you will get in trouble when the objects are not in that thread. It's not worth the trouble.
But if it's in the same thread, QCoreApplication will block the program from running. How should I solve this?
-
@pedisChen said in When calling the Shared Libraries (DLL) created by QT6, the main program will crash:
But if it's in the same thread, QCoreApplication will block the program from running. How should I solve this?
Like I've said above, create a new
std::thread
for yourQ(Core)Application
. -
@Pl45m4 Thank you for your reply. I tried. here is my example code:
Version A
void start_app(void) { int argc = 0; char*argv[] = {nullptr}; QCoreApplication a(argc, argv); a.exec(); } void init_dll() { std::thread th(start_app); h.detach(); }
I use QLibrary to resolve "init_dll" function and run it.This time the main program is not blocked, no crash down occured .But the signal slot did not work, and QTCPSocket cannot be used.
Version B
void start_app(void) { int argc = 0; char*argv[] = {nullptr}; QCoreApplication a(argc, argv); a.exec(); } void init_dll() { start_app(); }
when I call "init_dll" function in DLLs,the main program will be blocked from running, but the QTCPSocket and signal slots function is workable.
How can I modify the DLL code so it doesn't block the main program's execution and still allows using QTcpSocket and other Qt components that depend on the event loop(QCoreApplication)?
-
-
-