我正在编写客户端-服务器应用程序,它交换 OpenCL 函数并在服务器上执行它们。但是我无法正确链接 OpenCL。程序编译但运行时显示 0xc000007b
错误。
- 我正在使用
Visual Studio 15 2017
- 整个解决方案是为
x64
构建的 - 每个依赖项都是
x64
,并且在链接OpenCL
之前可以完美运行。 - 我正在使用
Intel SDK 平台
(最新)。 - 重要,只要我包含
cl.h
header ,与CMake
链接,并且不使用任何OpenCL
函数,一切正常。 - 我正在使用 cmake 进行构建,但此时(我真的尝试了所有方法)任何解决方案都会让我满意,甚至在 VS 中手动更改属性也是如此。
我知道错误代码 0xc000007b
是由将 x32 dll 加载到 x64 项目引起的,但我认为这不是这里的问题。
主要 CMake:
find_package(OpenCL REQUIRED)
# include directories
include_directories(${OpenCL_INCLUDE_DIRS})
message(STATUS "opencl_include: " ${OpenCL_INCLUDE_DIRS})
# link libraries
link_directories(${OpenCL_LIBRARIES})
message(STATUS "opencl_lib: " ${OpenCL_LIBRARIES})
服务器CMake:
add_executable(server ${SRC_HEADERS} ${SRC})
target_link_libraries(server
${OpenCL_LIBRARY}
)
CMake 输出:
opencl_include: C:/Intel/OpenCL/sdk/include
opencl_lib: C:/Intel/OpenCL/sdk/lib/x64/OpenCL.lib
在 Build/bin/Debug
目录下正确创建 OpenCL.dll。我尝试将文件复制到源目录中,在 cmake 中手动链接它并在 Visual Studio 中设置属性而不是 cmake。还是一样的问题。
我已缩短代码以仅显示重要部分,如果我遗漏了任何相关内容请告诉我,我会将其包含在我的问题中。
编辑:
我还尝试链接 x86 OpenCL.lib 版本,在那种情况下会出现编译错误:
unresolved external symbols
最佳答案
错误可能有多种原因,但要开始进行故障排除,您可以验证以下内容:
1) 您是否实际构建了 64 位 DLL 而不是 32 位 DLL,并且
2) Windows 本身实际上是在运行时加载您的 64 位 DLL,而不是碰巧与 64 位 DLL 具有相同文件名的 32 位 DLL。
对于 1),您可以使用 dumpbin
,或类似 Dependency Walker 的实用程序验证正在构建的 DLL 是 64 位的。
如果在应用步骤 1) 后,您已验证 DLL 是 64 位,则下一步要验证的是步骤 2)。由于您在评论中提到您已验证正在构建的 DLL 是 64 位的,那么您应该尝试步骤 2)。
对于步骤 2),当 Windows 尝试在运行时加载 DLL 时,Windows 遇到的第一个与 DLL 文件名匹配的名称将被加载,无论它是否是正确的 DLL 的位数级别。当有 2 个(或更多)DLL 具有完全相同的名称,但具有不同的“位数”级别,即与应用程序相比是 32 位或 64 位时,就会出现问题。
如果您运行的是 64 位应用程序,而 Windows 试图加载 32 位 DLL,那么您将收到 0xc0000007b
错误——反之亦然,加载 64 位 DLL位 DLL 到 32 位应用程序会导致发生相同的问题。
This link描述了 Windows 在加载 DLL 时使用的搜索逻辑。确保 Windows 不会无意中选择与名称匹配但应用程序位级别不同的 DLL。
对于大多数重要的情况,此错误将是在系统路径上找到不正确的 DLL,因此 Windows 会尝试加载它。但正如链接所暗示的那样,还有其他情况会导致 Windows 选择 DLL(太多无法一一列举,因此请查看发布的链接)。
不幸的是,这就是 Windows 的工作方式,所以当您同时拥有同名的 32 位和 64 位版本的 DLL 时要小心,并且其中一个或另一个可能会被 Windows 加载。
关于c++ - Windows 上 OpenCL 库的 0xc000007b 加载时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52352899/