Почему "точка входа в процедуру не может быть найдена в dll", когда я ее определенно вставил?
У меня действительно смутная проблема, но я надеюсь, что кто-то может помочь с этим. Я модифицировал проект C++, и вчера он все еще работал, но сегодня это не так. Я почти уверен, что ничего не изменил, но чтобы быть полностью уверенным, я снова извлек проект из SVN и даже вернулся к предыдущей точке восстановления системы (поскольку это рабочий компьютер, иногда он тайно устанавливает обновления и т. Д.). После успешной компиляции программа может запуститься, но после того, как я с ней взаимодействую, я получаю такую ошибку:Точка входа в процедуру? MethodName@className@@UAEXXZ не может быть расположена в библиотеке динамических ссылок libName.dll.
Я искал в Интернете, но проблемы большинства людей, кажется, вызваны более старой версией используемой DLL. Я искал свой компьютер, и нет более старой версии. Если я удаляю правильную версию, приложение не запускается. Если я затем перекомпилирую проект, DLL будет создана снова, поэтому я почти уверен, что приложение использует правильную DLL и что ее создает компиляция. Если я добавлю синтаксические ошибки в метод, к которому относится ошибка, проект откажется компилировать, поэтому я предполагаю, что это означает, что он также компилирует файлы, содержащие метод.
По сути, я ничего не знаю о библиотеках DLL, ссылках и т. Д., Поэтому я был бы очень признателен, если бы у кого-то было представление о том, почему функции, которые очень четко определены в проекте, вдруг перестают попадать в DLL., Я знаю, что это расплывчато, и если потребуется дополнительная информация, я с радостью предоставлю ее. Спасибо!
Обновление: я попробовал данные предложения, но я все еще застрял. __declspec(dllexport)
по-видимому, не используется во всем проекте. Открытие DLL с помощью Dependency Walker показывает мне пустой верхний правый раздел, а в разделе под ним перечислены функции из сообщения об ошибке. Если я проверяю Undecorate C++ Functions, он выглядит нормально, но если я не проверяю, я получаю странные вопросительные знаки и @s из сообщения об ошибке, и в конце появляется разница:
?methodName@className@@UAEXXZ
?methodName@className@@UAEXH@Z
Возможно, это проблема, но я понятия не имею, что это значит, что, возможно, вызвало это и что я могу с этим поделать.
4 ответа
Я чувствую себя немного глупо, но я нашел ответ. Приложение (exe), которое я использовал, очевидно, загрузило вторую, другую DLL, которая зависела от той, что упоминалась в моем первоначальном посте. Эта вторая DLL все еще ожидала старых функций и также должна была быть перекомпилирована против обновленной DLL.
Большое спасибо людям, которые пытались помочь мне здесь!
Вы на самом деле используете __declspec(dllexport)
? Я предполагаю, что нет - без этого объявления эта функция не будет экспортироваться DLL (или, другими словами, программы, загружающие эту DLL, не будут иметь доступа к функциям без этого объявления).
Кроме того, попробуйте использовать Dependency Walker, чтобы увидеть, какие именно функции предоставлены вашей DLL.
Дело в том, что __declspec(dllexport)
не используется в объявлениях функций, это нормально - в большинстве случаев он будет использоваться только один раз в одном заголовочном файле, например
#ifdef MAKING_DLL
#define FOO_API __declspec(dllexport)
#else
#define FOO_API
#endif
Так что если у вас есть #define MAKING_DLL
до этого раздела все функции, которые объявлены как FOO_API int BakeACake()
будет экспортироваться в зависимости от того, MAKING_DLL
был определен. Возможно, что проект ожидал MAKING_DLL
(или его эквивалент), который будет определен в командной строке, в зависимости от типа проекта (что-то вроде /DMAKING_DLL
; или вам может даже понадобиться определить FOO_API как /DFOO_API=__declspec(dllexport)
,
Пустой верхний правый раздел в Dependency Walker просто означает, что ваша программа не связывается с соответствующим DLL-файлом DLL. Это нормально, это просто означает, что вы используете LoadLibrary
или же LoadLibraryEx
для доступа к функциям в DLL.
Другой довольно вероятный сценарий (основанный на том факте, что искаженные имена отличаются) состоит в том, что программа была построена с использованием версии Visual Studio, отличной от версии 2008, которую вы использовали для сборки DLL. В отличие от простого C, нет стандартного двоичного интерфейса для C++, что означает, что вы должны использовать один и тот же компилятор для сборки программы и DLL, когда вы используете классы C++ в DLL. Если вы можете, попробуйте перестроить программу в VS2008, или попробуйте перестроить DLL в той же версии VS, что и программа.
Загрузите обходчик зависимостей и откройте свою DLL, используя этот инструмент. Он покажет список экспортируемых функций из вашей DLL. Проверьте, является ли вышеупомянутый метод частью ожидаемых функций. Если это не так, то это означает, что вы случайно удалили __declspec(dllexport)
для одного из классов в этой DLL.
Используя информацию из постов выше, я нашел простое общее решение. Все, что вам нужно сделать, это открыть программы, исполняемые с помощью обходчика зависимостей, найти отсутствующие функции, посмотреть, что использует dll, найти проект, который собирает эту dll, и перестроить ее.