动态加载QTGui
Dynamically Loading QTGui
我正在编写一个QT应用程序,我希望编译的二进制文件与GUI和CLI(在没有X11的情况下安装)环境兼容。
以下是我使用QApplication或QCoreApplication的主要功能:
int main(int argc, char *argv[]){
// SOME COMMON CODE will be executed before this
bool myGUI = getenv("DISPLAY") != 0;
if(myGUI){
QApplication a(argc, argv);
client w; // A MainWindow Object
w.show();
doStuff();
return a.exec();
}else{
QCoreApplication a(argc, argv);
doStuff();
return a.exec();
}
return 1;
}
现在,QT构建了一个二进制文件,其中libQtGui是一个动态共享对象。我想知道是否可以动态加载libQtGui,这样它就可以在CLI环境中工作,而不必安装libQtGui所需的所有库。
尝试这样做是不现实的。这在理论上是可能的,但您需要为大量内容创建C包装器。
相反,您可以尝试将应用程序的GUI部分拆分为自己的共享库和dlopen()。例如,gui.cpp:
// Needs to be extern "C" so that dlopen() can find it later.
extern "C"
int runGui(int argc, char *argv[])
{
QApplication a(argc, argv);
client w;
w.show();
doStuff();
return a.exec();
}
您将以上内容编译为一个共享库,链接到QtGui。例如:
g++-c-fPIC$(pkg配置QtGui--cfglags)-o gui.o gui.cppg++-shared-o gui.so gui.o$(pkg配置QtGui--libs)
这将为您提供gui.so
,然后您可以在主程序中dlopen()
#include <dlfcn.h>
int main(int argc, char *argv[])
{
// SOME COMMON CODE will be executed before this
bool myGUI = getenv("DISPLAY") != 0;
int ret = 0;
if (myGUI) {
void* handle = dlopen("./gui.so", RTLD_NOW);
if (!handle) {
// Error: dlopen failed
}
dlerror(); // Clear/reset errors.
// Create a function pointer type for runGui()
typedef int (*runGui_t)(int, char**);
// Load the address of runGui() and store it in a
// function pointer. The function pointer name doesn't
// have to be the same as the function we're loading.
runGui_t runGui = (runGui_t)dlsym(handle, "runGui");
const char* dlsym_error = dlerror();
if (dlsym_error) {
// Error: dlsym failed.
// 'dlsym_error' contains the error msg.
}
// Call the function as usual by using our 'runGui' pointer.
ret = runGui(argc, argv);
dlclose(handle);
} else {
QCoreApplication a(argc, argv);
doStuff();
ret = a.exec();
}
return ret;
}
请注意,在构建上述main.cpp时,您不能链接到QtGui,这样它将在libQtGui.so不可用的系统上运行。在这种情况下,dlopen()将无法加载gui.so。此时,您可以返回到非gui代码(我在上面的示例中没有这样做。)
这不是关于Qt的问题,而是关于c++的问题
你可以在这里找到答案从DLL 动态加载函数
但基本上我认为这是个坏主意,如果你想要一个纯控制台应用程序或混合控制台/gui应用程序,你应该在编译时用#ifdef来解决它。
#ifdef WITH_GUI
if(myGUI){
QApplication a(argc, argv);
client w; // A MainWindow Object
w.show();
doStuff();
return a.exec();
}else{
#endif
QCoreApplication a(argc, argv);
doStuff();
return a.exec();
#ifdef WITH_GUI
}
#endif
并添加一些启动参数。例如/myapp——启动gui,用于使用gui支持编译的版本。
相关文章:
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- Python ctypes:不会按预期加载 dll
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 保存/加载大量短数组到二进制文件
- 使用 SDL2 和SDL_image C++加载图像
- 无法使用加载库卸载注入的 dll (C++)
- 是否有原子加载非原子值的函数?
- 将 bmp 文件加载到 TSpeedButton 中
- QtGUI:加载二进制像素图的最快方法是什么
- 动态加载QTGui