Ошибка времени загрузки 0xc000007b с библиотекой OpenCL в Windows - PullRequest
0 голосов
/ 16 сентября 2018

Я пишу приложение клиент-сервер, которое обменивается функциями 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 в проект 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. Все та же проблема.

Я сократил код, чтобы показать только важные части, если я пропустил что-то важное, дайте мне знать, я включу его в свой вопрос.

EDIT:

Я также пытался связать версию OpenCL.lib для x86, в этом случае возникает ошибка компиляции:

неразрешенные внешние символы

1 Ответ

0 голосов
/ 16 сентября 2018

Причин может быть несколько, но для устранения неполадок вы можете проверить следующее:

1) Независимо от того, создали ли вы 64-битную DLL, а не 32-битную DLL,

2) Сама Windows на самом деле загружает 64-битную DLL во время выполнения, а не 32-битную DLL, имя файла которой совпадает с именем 64-битной 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 в 32-разрядное приложение вызывает ту же проблему.

Эта ссылка описывает логику поиска, которую Windows использует при загрузке DLL. Убедитесь, что Windows непреднамеренно не получает библиотеку DLL, которая соответствует имени, но не совпадает с битовым уровнем приложения.

В большинстве нетривиальных ситуаций эта ошибка возникает, когда в системном пути обнаруживается неверная DLL, и, следовательно, Windows пытается загрузить ее. Но, как следует из ссылки, существуют другие сценарии, которые заставляют Windows выбирать DLL (слишком много, чтобы упоминать, поэтому посмотрите на опубликованную ссылку).


К сожалению, именно так работает Windows, поэтому будьте осторожны, если у вас есть как 32-, так и 64-разрядные версии DLL с одинаковым именем, и существует вероятность того, что одна или другая версия будет загружена Windows.

...