2012-04-12 103 views
3

延迟DLL加载可能在QT中? 例如,我的程序依赖于某些第三方DLL,我想将其删除。QT中的延迟DLL加载问题

我应该在.pro文件中写入什么来消除依赖关系?

我可以在资源中存储DLL吗?

我可以加载DLL“全局”吗?所以DLL中的某些函数(例如func1)在我的代码中将保持func1。

回答

5

是的,你想使用QLibrary类。它专门用于在运行时加载共享库。

在这种情况下,你的.pro文件中不需要任何东西。但是,您需要确保该DLL在目标计算机上可用。它需要位于系统可以找到它的位置(Windows上为PATH,Linux上为LD_LIBRARY_PATH,Mac上为DYLD_LIBRARY_PATH),或者您可以提供应用程序的绝对路径。

如果您查看文档,您将看到如何将库函数映射到代码中的函数指针,以便“func1()”将指向库中的函数。

[编辑]

这里是一个证明的概念从从资源所产生的临时文件加载DLL。海事组织,这是一个非常糟糕的想法,但它至少可以在我的Windows 7机器上运行。如果你想要做同样的事情,你将不得不处理清理临时文件,检查重复等

Foo.cpp中,编译成一个共享库

#include <QtCore/qglobal.h> 

extern "C" Q_DECL_EXPORT int foo(int value) { 
    return value + 42; 
} 

吧。亲,通知没有提及到foo库

SOURCES += main.cpp 
RESOURCES += resources.qrc 

的main.cpp

#include <QtCore> 
#include <iostream> 

int main(int argc, char **argv) { 
    QCoreApplication app(argc, argv); 

    // Copy resource dll to temporary file. 
    QFile::copy(":/lib/Foo.dll", QDir::temp().filePath("Foo.dll")); 

    // Load the temporary file as a shared library. 
    QLibrary foo_lib(QDir::temp().filePath("Foo.dll")); 
    typedef int (*FooDelegate)(int); 
    FooDelegate foo = (FooDelegate)foo_lib.resolve("foo"); 

    if (foo) { 
    std::cout << "foo(13) = " << foo(13) << std::endl; 
    } 
} 
+0

+1。谢谢你的回答。但我的问题是DLL在目标计算机上不可用...所以我想删除依赖项,将其存储在资源中,并在可能的情况下动态加载。此外,用户应该只看到一个.exe文件,而无需安装... – Eddie 2012-04-12 14:38:10

+0

哦,我明白了。你可能已经想到了这一点,但是你能得到一个你可以静态链接的库的版本吗?最后,这听起来像是你想达到的目标。 – 2012-04-12 17:15:02

+1

如果你不能静态链接,你可以在你的main()方法中尝试*,将DLL作为二进制资源加载并放在某个特定的位置,比如系统的临时目录,然后使用'QLibrary'从那里加载它。但是,这是一种非常糟糕的代码味道,而且您可能有安全问题。 – 2012-04-12 17:16:48

3

我只能从微软编译器的角度来讲......它不依赖于QT想要什么,而是在何时何地访问延迟加载的代码和/或数据。

一般来说,您必须告诉链接程序该DLL延迟加载了/delayload:[dllname]选项并与delayimp.lib链接。您可以在.cpp文件与

#pragma comment(lib, "delayimp")

添加库,将删除需要指定它的链接器命令行上。

我不确定.pro文件中的内容是否将延迟加载开关添加到链接器命令中。

请参阅this link Microsoft文档。

+0

感谢您的回答。但是我不知道在QT中写入'/ delayload:[dllname]'的位置...... QT还会返回“忽略编译注释”。 – Eddie 2012-04-12 14:34:40