【发布时间】:2020-08-12 00:55:13
【问题描述】:
我正在为 Windows 编写一个非常小的基于 C/C++ Qt 的应用程序(仅限 Windows——根本不是跨平台),它使用 VISA 库 (visa64.dll) 与一些外部硬件通信。反过来,该库使用其他一些库:
(来自 Dependency Walker 又名dependency.exe 的屏幕截图)
最初我是在 Visual Studio 中编写的,效果很好。然后我将它移植到 Qt Creator(使用 Qt5,w/MSVC 2015 Visual C++ 工具链),我得到了运行时错误。它知道在哪里可以找到外部头文件,所以我认为我的 INCLUDEPATH 是正确的,并且它构建得很好,所以我认为我的 .pro 文件中的 LIBS 变量是正确的,也就是说它可以找到它需要的 .lib 文件。但是,我从这个外部库 (viOpenDefaultRM) 调用的第一个 API 返回以下错误:VI_ERROR_LIBRARY_NFOUND。无论我是进行调试构建还是发布构建,以及是否使用调试器运行它,都会发生这种情况。只要我从 Qt Creator 中运行程序,它就会出现运行时错误。
这是我的 .pro 文件:
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
INCLUDEPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'
LIBS += -L$$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Lib_x64/msc/' -lvisa64
INCLUDEPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'
DEPENDPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'
以/Include 结尾的路径有头文件(.h)(它是一个C 库),以/msc 结尾的路径有一个.lib 文件。 .lib 文件不是静态库,它们是一些相应 DLL 的接口文件。这些 DLL 文件位于 C:\System32 中。 C:\SysWOW64 中也有 32 位版本。它们也可能存在于其他地方,但如果它们存在,我不知道。
现在,如果我从 cmd.exe 运行它,它工作正常。也就是说,如果我打开一个 cmd.exe 终端窗口并导航到我的 Qt 项目的构建目录 (c:\blah\blah\blah\obj\debug\) 并从 cmd.exe 运行可执行文件,我不会收到运行时错误。它可以连接到外部硬件,与它交谈,所有美好的事情都在发生,非常高兴。
我已经对这个问题进行了大量的搜索和研究,但我有点被大多数人遇到相反问题的事实所诅咒,这意味着 那个 问题(相反的一个我的)是在 Google/DuckDuckGo/StackOverflow/forum.qt.io/doc.qt.io 搜索中出现的内容。该问题通常与丢失/放错的 Qt 库有关。 Here 就是一个例子。这个问题的答案通常以一个链接结束,该链接指向如何为 Windows 部署 Qt 项目的页面,例如this article.
我还阅读了来自 Qt 的 this 关于如何将库添加到您的项目的文章,但它并没有帮助我,但我可能遗漏了一些东西和/或做错了。
这可能是我想念的一些非常愚蠢的东西,坦率地说我希望它是。谢谢*10^6。
【问题讨论】:
-
您是否尝试静态链接?我想是的,因为这是一个.lib。您是否尝试过指定库的扩展名(例如 visa64.lib)?究竟是什么产生了这个 VI_ERROR_LIBRARY_NFOUND 错误?因为根据您的链接方式,您应该会在运行时看到一个编译时错误,指出库丢失、找不到文件或未定义符号。顺便说一句,您已将两次 INCLUDEPATH 添加到 VISA,但这并不重要。
-
我正在尝试动态链接,尽管我可能会对其进行比较。但是 .lib 文件只是 system32 中相应 DLL 中的所有符号。我认为 .lib 文件就像在这种情况下为 visa64.dll 调用了一堆 LoadLibraryA() ,但库的编译代码在 visa64.dll 中。如果我理解正确。所以我相信 .lib 文件必须存在才能编译项目,但在运行时 DLL 是 API 的实际编译代码所在的位置。 VI_ERROR_LIBRARY_NFOUND 表示通常无法找到或加载 VISA 或 VISA 需要的库。
-
对,不要再那么频繁地做 Windows 开发了!所以我所说的“什么是产生错误VI_...”的意思是我很惊讶它会这样显示,除非有东西在运行时寻找它并链接到它,就像插件一样。这意味着您首先甚至不需要
-lvisa64。会不会是viopenDefaultRM()失败,因为正确的插件/文件不在其查找的路径中?在这里,您尝试使用-l在链接器中将其注册为依赖库,但在我看来,应用程序启动正常,然后它尝试加载visa64并失败 -
... 我会假设 viopenDefaultRM() 在特定位置寻找它,只是没有找到它
-
我认为你是对的,
viOpenDefaultRM()失败 b/c 它找不到正确的插件/文件,也许是 DLL,它正在寻找的地方。我认为。我认为即使在我的代码中调用viOpenDefaultRM(),它也可以编译的原因是因为-lvisa64标志是指visa64.lib。 visa64.lib 我认为它提供了来自其他地方的 DLL (visa64.dll) 的 API 名称。所以我猜它要么因为某种原因不知道在哪里可以找到 visa64.dll,要么它在错误的地方寻找我不知道的不同版本的 visa64.dll。
标签: c++ windows visual-c++ qt-creator visa