Windows上的OpenCL库出现0xc000007b加载时间错误

时间:2018-09-16 09:49:02

标签: c++ cmake opencl

我正在编写客户端-服务器应用程序,该应用程序交换OpenCL函数并在服务器上执行它们。但是,我无法正确链接OpenCL。程序已编译,但运行时显示0xc000007b错误。

  1. 我正在使用Visual Studio 15 2017
  2. x64构建了整个解决方案
  3. 每个依赖项都是x64,并且在链接OpenCL之前是完美的。
  4. 我正在使用Intel SDK platform(最新)。
  5. 重要,只要我包含cl.h标头,与CMake链接且不使用任何OpenCL函数,一切正常。
  6. 我正在使用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版本,在这种情况下会出现编译错误:

  

未解析的外部符号

1 个答案:

答案 0 :(得分:1)

该错误可能有多种原因,但是要开始进行故障排除,您可以验证以下内容:

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。当有两个(或多个)具有相同确切名称的DLL,但具有不同的“位数”级别(即,与应用程序相比为32位或64位)时,就会出现问题。

如果您运行的是64位应用程序,而Windows尝试加载32位DLL,则会出现0xc0000007b错误-反之亦然,即加载64位DLL进入32位应用程序也会导致同样的问题。

This link描述了Windows在加载DLL时使用的搜索逻辑。确保Windows不会无意中拾取与名称匹配但与应用程序位级别相同的DLL。

对于大多数非常规情况,此错误将是在系统路径上找到错误的DLL并因此Windows尝试加载它的错误。但是正如该链接所暗示的那样,还有其他情况会导致Windows选择DLL(要提的太多,因此请查看发布的链接)。


不幸的是,这就是Windows的工作方式,因此当32位和64位版本的DLL具有相同的名称时,请当心,并且Windows可能会加载一个或另一个。 >