Процедура точки входа MS VS 2010 не может быть найдена после изменения имени процедуры

Вот загадка, на которую я не могу найти ответ (здесь, на SO или других сайтах). Я новичок в SO, но я пытаюсь учиться быстро.

Мне нужно изменить имя моей процедуры точки входа dll с

int subCreatePipe()

в

int subCreateNewPipe()

Но запускающая программа умирает, когда я это делаю.

Конкретная ошибка:

«Не удалось найти точку входа в процедуру subCreateNewPipe в библиотеке динамических ссылок myPipe.dll»

Настройки, на которых я работаю:

  • Windows 7
  • MS Visual Studio 2010
  • C ++ Win32
  • Неуправляемый (без CLI)
  • MBCS

    • Я создал «myPipe.dll» (используя вышеуказанные настройки), чтобы проверить свою способность создавать DLL и открывать канал.
    • Я создал «TestPipe.cpp» (используя вышеуказанные настройки, но с консолью Win32), чтобы я мог запустить программу, которая будет ссылаться на DLL и отображать некоторые результаты для меня.
    • (У меня также есть другая программа, которая отправит что-то в канал.)

Теперь вот кикер:

  1. Я создал DLL с процедурой под названием int subCreatePipe() в этом.
  2. Я скомпилировал это с успехом.
  3. Я перемещаю файлы релиза в свой TestPipe подпапка проекта «Lib».
  4. В TestPipe.cpp у меня есть строка для вызова процедуры:

    x = subCreatePipe();
    
  5. Я компилирую TestPipe.cpp и запускаю выпуск «TestPipe.exe», и он работает отлично.
    Находит точку входа в subCreatePipe.

Но мне нужно переименовать процедуру DLL в subCreateNewPipe придерживаться соглашения об именах, которое я не могу контролировать.

  1. Я переименую процедуру в myPipe.dll, чтобы int subCreateNewPipe()
  2. Я скомпилировал это с успехом.
  3. Я перемещаю файлы релиза в подпапку «Lib» проекта TestPipe. (удаляя старые файлы)
  4. В TestPipe.cpp я изменяю вызов процедуры на:

    x = subCreateNewPipe();
    
  5. Я компилирую TestPipe.cpp и запускаю релиз «TestPipe.exe», и он умирает (с ошибкой, приведенной выше).

Если я вернусь и изменим имя DLL-процедуры на subCreatePipe, он снова запустится. Если я вернусь и изменить его на subCreateNewPipeопять умирает. Единственное, что я делаю по-другому, это изменение имени процедуры точки входа.

Итак, мои вопросы:

  1. Есть ли способ переименовать процедуру входа в VS 2010?
  2. Должен ли я использовать DLLMain() хотя я бы просто оставил это пустым? (Это кажется плохой формой.)
  3. Есть ли какой-то скрытый переключатель, который мне не хватает?
  4. Что на самом деле происходит с компоновщиком?
  5. Происходит ли искажение имени?
  6. Или есть что-то еще, что нельзя изменить после первой компиляции проекта?

Несколько других вещей, которые я попробовал (которые все еще дают те же результаты «первого способа работы», но «второго способа не получается»):

  • Я пытался с помощью __stdcall

    int __stdcall subCreatePipe() // works
    int __stdcall subCreateNewPipe() // doesn't work
    
  • Я пытался с помощью __declspec(dllexport)

    ifdef X_EXPORT_FLAG
    #define DLL_IMPORT_EXPORT __declspec(dllexport)
    else
    #define DLL_IMPORT_EXPORT __declspec(dllimport)
    endif
    
    X_EXPORT_FLAG int __stdcall subCreatePipe() // works
    X_EXPORT_FLAG int __stdcall subCreateNewPipe() // doesn't work
    
  • Я также попытался использовать файл .DEF, чтобы определить имя процедуры для компоновщика.

    int subCreatePipe() // works
    int subCreateNewPipe() // doesn't work
    

(Во всех примерах я изменяю код TestPipe.cpp для вызова правильного имени процедуры.)

Если вы не можете сказать, я немного обеспокоен попытками выяснить, как заставить это работать.

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

0

Решение

РЕШЕНИЕ:

В Неуправляемый C ++, библиотеки DLL не удаляются из папки «Release», как в Managed C ++. Вы должны физически перемещать новую DLL в папку «Release» вашей прикладной программы каждый раз, когда вы вносите изменения в свою DLL.

Я узнал, как бороться с обновлением DLL в Удалось C ++, где все, что вам нужно сделать (в папке вашей прикладной программы) — очистить старую подпапку библиотеки DLL и скопировать новую версию измененных DLL в эту пустую подпапку библиотеки. Когда вы «очищаете и перестраиваете» приложение, которое вызывает эти DLL, Удалось VS2010 C ++ удалит старые DLL из папки «Release» и скопирует новые DLL из подпапки библиотеки в папку «Release» приложения. Это хорошо держит вашу DLL в актуальном состоянии.

В Неуправляемый C ++, «Очистить и восстановить» делает не удалите ваши старые DLL из папки «Release» приложения. И это не скопируйте новую DLL из вашей подпапки библиотеки либо. Поэтому, хотя я и думал, что помещаю свои новые DLL в папку, в которой моя программа могла их найти, они не копировались, как в Managed C ++.

Когда Майкл Берр дал мне link /dump /exports myPipe.dll инструменты, я смог увидеть метку времени DLL и процедуры, которые были доступны. (В моем случае это была первая сборка DLL, в которой была только одна процедура.) Было очевидно, что это старая DLL, а не текущая.

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

Еще раз спасибо! 🙂

0

Другие решения


По вопросам рекламы [email protected]