|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июл 25, 2003 23:36:24 · Поправил: volodya Вопрос о старой привязке. Проблема: есть Dll, положим, у которой ручками приделана API-функция, которая немедленно форвардится куда-то, предположим, это будет Hi. Имеем: dll.def
EXPORTS
Hi = USER32.MessageBoxA
Теперь exe. Когда зовется LoadLibrary/GetProcAddress - все нормально. Функцию можно вызвать. Что-то где-то так: Hi(NULL, "Ща спою", "Не, ща точно спою!", MB_OK); Если позвать указателем на функцию после GetProcAddress, то все ОК, если попытаться слинковать статически - ничего не выходит. Unresolved external Hi и хоть ты умри. Я бы думал, что это вообще невозможно, но есть же kernel32.dll, где тоже есть форварды, и линкуется статически, собака! Точно, я что-то неправильно линкую! Или где-то что-то неверно определяю! Да, extern "C" не предлагать! |
|
|
Дата: Июл 26, 2003 00:01:38 А нормальные экспорты (без forward) из этой DLL линкуются? но есть же kernel32.dll А ты использовал форварды из kernel32.lib? Или где-то что-то неверно определяю! Верно подмечено :) Это всё под VC? |
|
|
Дата: Июл 26, 2003 00:04:40 · Поправил: volodya А нормальные экспорты (без forward) из этой DLL линкуются? Канечно, дарагой! А ты использовал форварды из kernel32.lib? Их использовал любой, кто хоть раз звал HeapAlloc и т.п. Просто линкер меня не пропускает при статической линковке. Можно создать файл руками, но ЭТО НЕ ВЫХОД! Все под VC. Проблема в том, что Hi незаманглена в таблице экспорта dll, а компилятор манглит ее в таблице импорта exe и ессно, ждет, что увидит нечто такое в dll, а его там нет :( |
|
|
Дата: Июл 26, 2003 01:21:57 Hi незаманглена в таблице экспорта dll В EXP'е её обзывают как _Hi@16, а VC ищет просто _Hi (без @16)... |
|
|
Дата: Июл 26, 2003 02:31:31 Разобрался, вроде... Так вот, определил я этот Hi просто как H: EXPORTS H = USER32.MessageBoxA Линкер обозвал это дело _H@16 Я открыл lib в хексе и заменил все _H@16 на _HHHH. Потом, в VC, extern "C" int HHHH(int,char*,char*,int); . . . HHHH(NULL, "Ща спою", "Не, ща точно спою!", MB_OK); Даже karaoke запустил для реализма :) ЗЫ: Другого способа я не нашёл... |
|
|
Дата: Июл 26, 2003 05:31:24 Quantum А линкер и не ожидал такой безцеремонной подмены и схавал за милую душу :-) Опять сплоховало чудо программерской мысли от Microsoft перед живым человеческим гением, свежа в памяти ещё недавняя история с DLL2LiB :-))))) |
|
|
Дата: Июл 26, 2003 05:35:29 Хреново. А как же тогда статически слинковать по ординалу? Опять хаканьем либы? ЭТО НЕ ВЫХОД! |
|
|
Дата: Июл 26, 2003 06:06:45 Asterix :))) volodya А как же тогда статически слинковать по ординалу? ?! Не понял... Я ж как раз статически всё и слинковал. Хаканье либы элементарно проделать посредством search&replace в WinHex. Может я не так понял проблему? ЗЫ: Я не совсем догоняю почему в VC и MASM32 такие различия на стадии линковки (линкер ведь почти один и тот же) Копался я тут с параметрами командной строки LINK.EXE и ничего конкретного про @XX не нашёл :( |
|
|
Дата: Июл 26, 2003 18:57:07 Не понял... Поясняю. Ты делал линк по имени. Можно, чтобы не мучатсья с хаканьем либы, попытаться слинковать по ординалу. Для этого в таблице экспорта dll: EXPORTS H = USER32.MessageBoxA @5 NONAME Все, тогда в таблице экспорта никакого H не будет, будет только пятерочка. Динамически ее можно позвать GetProcAddress(MAKEINTRESOURCE(5)); как прилинковать по ординалу статически - я не знаю :( |
|
|
Дата: Июл 26, 2003 19:35:37 volodya Точно... Я об этом когда-то читал, но никогда ординалами не пользовался. Сейчас поэкспериментируем... Asterix Если ординалы можно юзать для статической линковки, хак для Dll2Lib радикально упрощается... Правда, я в этом сильно сомневаюсь (линкер вряд ли сможет определить в какой именно либе следует ресолвить ординал) |
|
|
Дата: Июл 26, 2003 20:06:24 Копался я тут с параметрами командной строки LINK.EXE и ничего конкретного про @XX не нашёл :( А не нашёл я ничего потому что этот @XX добавляет не линкер а компилятор! MASM32 превращает "Hi PROC" в _Hi@0. |
|
|
Дата: Июл 26, 2003 21:28:32 volodya как прилинковать по ординалу статически Эврика!!! Экспертиза завершилась успешно! Модификатор NONAME убирает имя ф-ции из таблицы экспорта DLL, но в LIB импорта это имя таки попадает. Поэтому HHHH(int,char*,char*,int) можно спокойно объявлять в VC (проверил). Проблема с манглом пока ещё не решена... |
|
|
Дата: Июл 26, 2003 22:47:06 Ммда... бросаю я это дело. В общем, проблему с манглом легко решить если реально экспортируется ф-ция (не форвард) двумя способами (помимо хака): 1. Убрать мангл вообще. Для этого достаточно объявить SYSCALL в PROC и PROTO. 2. Произвольно заманглить примерно так: EXPORTS ?ownermangled@@XXYY@Z = realproc, где realproc -- это настоящее имя ф-ции в *.OBJ. НО оба метода бессильны перед форвардингом!!! Володя, передаю тебе эстафету :) |
|
|
Дата: Июл 27, 2003 01:28:18 Ок, но я сошел с дистанции перед постом :( Сорри. Кстати, можешь утешить себя - никто из тех, с кем я советовался, не знает как решить проблему изящно. Хаканье либы - это несерьезно :) |
|
|
Дата: Июл 27, 2003 02:03:44 volodya Забыл добавить... Проблема имеет место только когда форвард идёт на STDCALL, вроде User32!MessageBoxA. Линкер "видит", что MessageBox определён (в user32.lib, например) как _MessageBoxA@16 и передаёт этот противный мангл на символ "Hi". Если пофиксить символ MessageBox в user32.lib, проблема решается автоматом, но потом прога не будет грузиться. С другой стороны, если таргет форварда определён как SYSCALL, проблем в этом отношении вообще не возникает. Смутное подозрение: в MS специально придумали этот манглинг шоб нам веселее жилось :) |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.047 |