Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QT中的延迟DLL加载_C++_Qt_Dll_Dynamic Loading - Fatal编程技术网

C++ QT中的延迟DLL加载

C++ QT中的延迟DLL加载,c++,qt,dll,dynamic-loading,C++,Qt,Dll,Dynamic Loading,QT中是否可以延迟加载DLL? 例如,我的程序依赖于某个第三方DLL,我想删除它 我应该在.pro文件中写入什么来删除依赖关系 我可以在资源中存储DLL吗 我可以“全局”加载DLL吗?因此,DLL中的某些函数(例如func1)将在我的代码中保持func1。是的,您希望使用QLibrary类。它专门用于在运行时加载共享库 在这种情况下,.pro文件中不需要任何内容。但是,您需要确保DLL在目标计算机上可用。它需要位于系统可以找到它的位置(Windows上的路径、Linux上的LD_LIBRARY_

QT中是否可以延迟加载DLL? 例如,我的程序依赖于某个第三方DLL,我想删除它

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

我可以在资源中存储DLL吗


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

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

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

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

[编辑]

下面是从资源生成的临时文件加载dll的概念证明。在我看来,这是一个非常糟糕的主意,但至少在我的Windows7机器上是可行的。如果你想做类似的事情,你必须清理临时文件,检查重复的文件,等等

foo.cpp,编译到共享库中

#include <QtCore/qglobal.h>

extern "C" Q_DECL_EXPORT int foo(int value) {
  return value + 42;
}
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;
  }
}
#包括
#包括
int main(int argc,字符**argv){
QCore应用程序应用程序(argc、argv);
//将资源dll复制到临时文件。
QFile::copy(“:/lib/Foo.dll”,QDir::temp().filePath(“Foo.dll”);
//将临时文件作为共享库加载。
QLibrary foo_lib(QDir::temp().filePath(“foo.dll”);
typedef int(*foodegate)(int);
foodedelegate foo=(foodedelegate)foo_lib.resolve(“foo”);
如果(foo){

std::cout我只能从Microsoft编译器的角度讲……它与其说取决于QT想要什么,不如说取决于何时何地访问延迟加载的代码和/或数据

通常,您必须告诉链接器DLL是使用
/delayload:[dllname]
选项延迟加载的,并使用delayimp.lib链接。您可以使用

#pragma注释(lib,“delayimp”)

这将消除在链接器命令行上指定它的需要

我不确定在.pro文件中添加delayload开关到linker命令的目的是什么


有关Microsoft文档,请参阅。

谢谢您的回答。但我不知道在QT中在何处写入
/delayload:[dllname]
。QT还返回“忽略pragma注释”.1.谢谢您的回答。但我的问题是目标计算机上没有DLL…因此我想删除依赖项,将其存储在资源中,并在可能的情况下动态加载。此外,用户在没有安装的情况下应该只看到一个.exe文件…哦,我明白了。您可能已经想到了这一点,但您可以获得库的版本吗你可以静态链接吗?这听起来像是你最终想要实现的目标。如果你不能静态链接,你可以在你的main()中尝试方法,将DLL作为二进制资源加载,并将其放在某个特定位置,如系统的临时目录,然后使用
QLibrary
从那里加载。但这是一种非常糟糕的代码味道,您可能会遇到安全问题。我想我可以将其作为资源存储,而无需创建新文件:)这是必需的吗告诉系统,我的exe没有对dll的依赖关系(或者它不会启动:()?…我认为你必须创建临时文件——这是系统库加载函数所期望的。因为所有加载都是在运行时基于魔法字符串,所以没有依赖关系;如果出现问题,你只会遇到严重的崩溃。
#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;
  }
}