Проблема с запуском 32-битной DLL с помощью rundll32.exe

Тема в разделе "WASM.BEGINNERS", создана пользователем JohnWoods, 26 ноя 2024.

Метки:
  1. JohnWoods

    JohnWoods New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2024
    Сообщения:
    2
    Всем привет!
    К сожалению, не являюсь специалистом по данной теме, решения в открытых источниках не нашлось, поэтому прошу помощи.
    Предполагаю, что допускаю нелепую ошибку новичка, поэтому заранее извиняюсь за возможно глупый вопрос.

    Есть следующий код DLL:

    Код (C++):
    1. BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    2. {
    3.     switch (ul_reason_for_call)
    4.     {
    5.         case DLL_PROCESS_ATTACH:
    6.             break;
    7.         case DLL_THREAD_ATTACH:
    8.             break;
    9.         case DLL_THREAD_DETACH:
    10.             break;
    11.         case DLL_PROCESS_DETACH:
    12.             break;
    13.     }
    14.     return TRUE;
    15. }
    16.  
    17. extern "C"
    18. __declspec(dllexport)
    19. void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
    20. {
    21.     // ...
    22. }
    Сборка в Visual Studio, с x64 все в порядке, у x86 возникает ошибка - "Нет точки входа EntryPoint".

    Причем картина идентичная с rundll32.exe в SysWOW64 и System32.
    Windows 64-bit.

    В чем может быть проблема?
     
  2. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    172
    В студии можно выбирать архитектуру при сборке проекта - x86/64-bit если не изменяет память
     
  3. JohnWoods

    JohnWoods New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2024
    Сообщения:
    2
    Как раз так и делаю, x64 сборка запускается исправно, у x86 сборки по какой-то причине не находится точка входа.
    --- Сообщение объединено, 26 ноя 2024 ---
    Возможно дело в соглашении о вызовых и для 32-bit нужно как-то переписать dllexport?
    --- Сообщение объединено, 26 ноя 2024 ---
    Да, действительно.
    Следующий код решает проблему:

    Код (Text):
    1. extern "C"
    2. __declspec(dllexport)
    3. void __cdecl Ent(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
    4. {
    5.     // ...
    6. }
    --- Сообщение объединено, 26 ноя 2024 ---
    Код (C++):
    1. // Calling Convention
    2. #ifdef _WIN64
    3. #define CALLBACK __stdcall
    4. #else
    5. #define CALLBACK __cdecl
    6. #endif
    7.  
    8. extern "C"
    9. __declspec(dllexport)
    10. void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
    11. {
    12.     // ...
    13. }
     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.330
    Потому, что под x86 будет не EntryPoint, а _EntryPoint, возьми любой PE просмотрщик типа PEAnatomist и посмотри таблицу экспорта.
     
    JohnWoods нравится это.
  5. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
    EntryPoint по соглашению должен быть __stdcall.
    Проблема в том, что на x32 компилятор при экспорте функций с соглашениями, отличными от cdecl, добавляет твоей функции декорирование с количеством байт на стеке под аргументы.
    В итоге твоя функция экспортируется не как "EntryPoint", а как "_EntryPoint@16", поэтому rundll32 её не видит.

    Чтобы экспортировать именно под тем именем, которое ты выбрал, требуется создать def-файл с описаниями экспортируемых функций.
    Создай в папке с проектом файл с расширением ".def" - например, Exports.def с таким содержимым:
    Код (Text):
    1.  
    2. EXPORTS
    3.     EntryPoint
    4.  
    Затем зайди в свойства проекта твоей библиотеки в раздел линкера и найди опцию, задающую путь к def-файлу:

    upload_2024-11-26_21-15-56.png

    После этого пересобери библиотеку, и экспорт теперь будет правильным:
    upload_2024-11-26_21-16-32.png
     
    JohnWoods, Mikl___, MaKsIm и ещё 1-му нравится это.