Почему «точка входа в процедуру не может быть расположена в dll», когда я ее определенно вставил? - PullRequest
6 голосов
/ 03 декабря 2009

У меня действительно смутная проблема, но я надеюсь, что кто-то может помочь с этим. Я модифицировал проект 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 ]

8 голосов
/ 03 декабря 2009

Вы действительно используете __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, что и программа.

2 голосов
/ 03 декабря 2009

Загрузите Ходок зависимостей и откройте свою DLL, используя этот инструмент. Он покажет список экспортируемых функций из вашей DLL. Проверьте, является ли вышеупомянутый метод частью ожидаемых функций. Если это не так, то это означает, что вы случайно удалили __declspec(dllexport) для одного из классов в этой dll.

1 голос
/ 08 декабря 2009

Я чувствую себя немного глупо, но я нашел ответ. Приложение (exe), которое я использовал, очевидно, загрузило вторую, другую DLL, которая зависела от той, что упоминалась в моем первоначальном посте. Эта вторая DLL все еще ожидала старых функций и также должна была быть перекомпилирована с обновленной DLL.

Большое спасибо людям, которые пытались мне здесь помочь!

0 голосов
/ 18 апреля 2011

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

...