我正在编写一个 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-config QtGui --cflags) -o gui.o gui.cpp g++ -shared -o gui.so gui.o $(pkg-config QtGui --libs)
This will give you gui.so
, which you can then dlopen() in your main program:
#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 代码(在上面的示例中我没有这样做。)
关于c++ - 动态加载QTGui,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17878779/