Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > При компиляции под x64 изменился экспорт библ-ки


Автор: ksili 29.9.2009, 06:09
Прошу вашей помощи, т.к. у меня самого 64-битного компа с 64-битной ОСью нет. Мне надо понять как исправить ошибку, а другой человек у себя это будет проверять. Поэтому буду рад любым замечаниям.

Есть одна и та же DLL скомпилированная под 32 и 64 бита. 
Под 32 бита всё работает. Под 64 бита не получается вызвать нужную функцию. Сравнил таблицы экспорта и обнаружил, что изменился прототип функции. Под 32 бита было:
Код

int __stdcall MyFunc(unsigned long,struct HWND__ *)

а под 64 стало:
Код

int __cdecl MyFunc(unsigned long,struct HWND__ * __ptr64)

Т.е. __stdcall превратился в __cdecl. Получается надо получать адрес функции уже по-другому. Раньше это делалось так:
Код

    BOOL (WINAPI *MyFuncProc)(DWORD dwThreadId, HWND wndServerWindow);
    (FARPROC&)MyFuncProc = GetProcAddress(hookDll, "MyFunc");

Видимо под 64 бита WINAPI это __cdecl, в то время как под 32 бита это __stdcall. Т.е. теперь, я думаю, как минимум стоит указать явно __cdecl вместо WINAPI:
Код

    BOOL (__cdecl *MyFuncProc)(DWORD dwThreadId, HWND wndServerWindow);
    (FARPROC&)MyFuncProc = GetProcAddress(hookDll, "MyFunc");

Или даже в самом объявлении функции обойтись без WINAPI, а указать явно __stdcall или __cdecl.
Кроме того, я не знаю, влияет ли на что-то изменение в объявлении записи второго аргумента со struct HWND__ * на struct HWND__ * __ptr64. Надо ли в связи с этим тоже что-то менять? 

Указанный код выполняется только в 64-битном приложении применительно к 64-битной DLL.

Автор: ksili 29.9.2009, 09:30
В MSDN в статье про __stdcall я нашёл следующее:
Цитата

On Itanium Processor Family (IPF) and x64 processors, __stdcall is accepted and ignored by the compiler;

И аналогично в статье про __cdecl:
Цитата

On Itanium Processor Family (IPF) and x64 processors, __cdecl is accepted and ignored by the compiler;

Чё-то я вообще не в понятках. Что тогда используется в x64?

Автор: Void 29.9.2009, 10:43
ksili, в Win x64 используется только один вид соглашений о вызове, не совпадающий ни с одним из 32-битных. Для передачи параметров используется до 8 регистров (RCX, RDX, R8, R9, XMM0-3).
http://msdn.microsoft.com/en-us/library/ms794656.aspx

Автор: jonie 29.9.2009, 11:12
Void, угу, там еще и RSP регистр (тот который в 32 бит зовется ESP) "не двигается" ... там много всякой фигни)

а по поводу "у меня нет винды 64 бит" - поставьте на вирт машину, например VMWare - она поддерживает ваиртуализацию процессора в том числе.

Автор: ksili 30.9.2009, 11:03
Спасибо за интересные ответы!

1) Насколько я понял чтобы не было проблем с calling convention под 64 бита надо при объявлении функции ничего про это не указывать. Ну и соответственно функции GetProcAddress подсовывать прототип безо всякого указания calling convention. Я правильно понял?

2) Скажите, какой дефайн определён в 64-битной винде? Это чтобы написать типа:
Код

#ifdef __WIN32
BOOL WINAPI MyFunc(DWORD dwThreadId, HWND wndServerWindow) {
#elif __X64
BOOL MyFunc(DWORD dwThreadId, HWND wndServerWindow) {
#endif


3) VMWare действительно может эмулировать 64-битный проц на 32-битном под 32-битной виндой? Я вроде уже спрашивал про такую возможность виртуалок, но мне что-то ничего не ответили. У меня есть Sun VirtualBox 2.1.0, там к сожалению процессор не указывается.

Автор: Void 30.9.2009, 11:06
Цитата(ksili @  30.9.2009,  13:03 Найти цитируемый пост)
VMWare действительно может эмулировать 64-битный проц на 32-битном под 32-битной виндой? Я вроде уже спрашивал про такую возможность виртуалок, но мне что-то ничего не ответили. У меня есть Sun VirtualBox 2.1.0, там к сожалению процессор не указывается.

Нет. VMWare и VirtualBox могут держать 64-битную гостевую систему под 32-битным хостом, но при условии что процессор 64-битный и поддерживает аппаратные расширения виртуализации.

Автор: ksili 30.9.2009, 11:34
Цитата(Void @  30.9.2009,  15:06 Найти цитируемый пост)
VMWare и VirtualBox могут держать 64-битную гостевую систему под 32-битным хостом, но при условии что процессор 64-битный и поддерживает аппаратные расширения виртуализации.

Подойдет ли такой процессор: http://ru.wikipedia.org/wiki/Turion_64_X2? Не могу там найти про поддержку аппаратных расширений виртуализации.

Добавлено через 5 минут и 41 секунду
Цитата(ksili @  30.9.2009,  15:34 Найти цитируемый пост)
Не могу там найти про поддержку аппаратных расширений виртуализации.

нашел, вроде поддерживает  smile 

Как насчёт

Цитата(ksili @  30.9.2009,  15:03 Найти цитируемый пост)

1) Насколько я понял чтобы не было проблем с calling convention под 64 бита надо при объявлении функции ничего про это не указывать. Ну и соответственно функции GetProcAddress подсовывать прототип безо всякого указания calling convention. Я правильно понял?
2) Скажите, какой дефайн определён в 64-битной винде?


Автор: ksili 30.9.2009, 12:07
Ну вроде нашёл - _WIN64. Теперь буду пробовать.

Автор: ksili 1.10.2009, 10:53
Не сработало.

Кто-нибудь может подсказать утилиту, которая хорошо разбирает PE-формат 64-разрядных файлов?

Автор: jonie 1.10.2009, 14:20
http://ru.wikipedia.org/wiki/Hiew
дожен быть неплох

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)