我正在编写客户端-服务器应用程序,该应用程序交换OpenCL函数并在服务器上执行它们。但是,我无法正确链接OpenCL。程序已编译,但运行时显示0xc000007b
错误。
Visual Studio 15 2017
x64
构建了整个解决方案x64
,并且在链接OpenCL
之前是完美的。Intel SDK platform
(最新)。cl.h
标头,与CMake
链接且不使用任何OpenCL
函数,一切正常。我知道错误代码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版本,在这种情况下会出现编译错误:
未解析的外部符号
答案 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可能会加载一个或另一个。 >