Здравствуйте, ekamaloff, Вы писали:
E>Здравствуйте, Ракопаукодав, Вы писали:
Р>>скажите, почему в dll при extern "C" и __stdcall имена функций становятся типа Func@16
E>Name Decoration
E>Там даже табличка есть, что и как декорируется при разных сочетаниях calling convention и extern "C"
Р>> и как этого избежать.
E>Использовать .def файл и поиск по RSDN.
.def файл я могу использовать при экспорте. А как мне его при импорте использовать? Я уже искал и не только по RSDN
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Р>.def файл я могу использовать при экспорте. А как мне его при импорте использовать? Я уже искал и не только по RSDN
Я не очень знаю C++, но, по моему, если ты не можешь собрать dll с def-файлом, то тебе уже на C++ ничего не поможет , я всегда знал, что Delphi — это круто, но что б настолько
P.S. Не слушай тех, кто ставит минусы за невнимательность, а сам даже ветку прочитать полностью не может
Здравствуйте, ekamaloff, Вы писали что надо внимательнее читать документацию, а вот векту вы прочитали невнимательно:
E>Использовать .def файл и поиск по RSDN.
спрашивал КАК это сделать
FDS>По моему, то что он хочеть просто невозможно
Вместо того, чтобы пытаться понять, что нужно сделать, и в чём у него проблема, он хочет доказать неправоту тех, кто хочет ему помочь. Так он очень долго промается со своей плёвой, честно говоря, проблемой.
Здравствуйте, Ракопаукодав, Вы писали:
Р>Простите за глупый вопрос, ситуация такая:
Р>нужно в VS2005 импортировать из dll функцию stdcall, однако при запуске программы он вместо функции Func ищет функцию, типа ?Func@XXZZYYA. Р>Использование директивы extern "C" не проходит, так как вызвать нужно именно stdcall
Попробуй для каждой ф-ции прописывать это:
#pragma comment(linker, "/export:MyFunc=?MyFunc@@YG_NH@Z")
это конечно не лучшее решение, но работает правда в експорте будут оба варианта ф-ции эффект тот же, что и от .def файла.
Р>2. почему в dll при extern "C" и __stdcall имена функций становятся типа Func@16 и как этого избежать. Минусы все ставить могут, а вот помочь советом почему-то за 2 дня ещё никто не смог
__stdcall добавляет @XXX, но это не является причиной вашей проблемы.
Если у Вас есть my.dll и вы хотите неявно загрузить её, то нужно использовать библиотеку импорта.
Это файл my.lib, который описывает экспортируемые функции. Он создается одновременно с my.dll и должен даваться разработчиками библиотеки.
Чтобы его использовать нужно дать линкеру соответсвующую комманду либо из проекта, либо в makefile, либо прямо в тексте исполняемой программы (#pragma comment(lib, "my.lib")
Даже если my.dll экспортирует "чистое" имя Func, то в библиотеке my.lib будет "нормальное" имя Func@0 и линкер легко найдет нужную функцию.
Если my.lib нет или библиотека была создана не MS совместимым компилятором, то это совершенно другой разговор.
Здравствуйте, MShura, Вы писали:
Р>>2. почему в dll при extern "C" и __stdcall имена функций становятся типа Func@16 и как этого избежать. Минусы все ставить могут, а вот помочь советом почему-то за 2 дня ещё никто не смог
MS>__stdcall добавляет @XXX, но это не является причиной вашей проблемы. MS>Если у Вас есть my.dll и вы хотите неявно загрузить её, то нужно использовать библиотеку импорта. MS>Это файл my.lib, который описывает экспортируемые функции. Он создается одновременно с my.dll и должен даваться разработчиками библиотеки. MS>Чтобы его использовать нужно дать линкеру соответсвующую комманду либо из проекта, либо в makefile, либо прямо в тексте исполняемой программы (#pragma comment(lib, "my.lib")
MS>Даже если my.dll экспортирует "чистое" имя Func, то в библиотеке my.lib будет "нормальное" имя Func@0 и линкер легко найдет нужную функцию. MS>Если my.lib нет или библиотека была создана не MS совместимым компилятором, то это совершенно другой разговор.
Кстати любопытный вопрос: можно ли статически связать свою прогу с чужой DLL (к примеру, подцепить NtQueryInformationFile из ntdll.dll) не имея к ней lib и не создавая для этого фейковый lib.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
CC>Кстати любопытный вопрос: можно ли статически связать свою прогу с чужой DLL (к примеру, подцепить NtQueryInformationFile из ntdll.dll) не имея к ней lib и не создавая для этого фейковый lib.
Боюсь, что стандартными линкерами тут не обойдешься.
Ведь линкер должен будет создать запись в таблице импорта и заглушки (корректируеются при загрузке библиотеки по конкретному адресу), для этого нормальному линкеру и нужна библиотека импорта (от пользователя) и список используемых функций (от компилятора).
CC>>Кстати любопытный вопрос: можно ли статически связать свою прогу с чужой DLL (к примеру, подцепить NtQueryInformationFile из ntdll.dll) не имея к ней lib и не создавая для этого фейковый lib.
MS>Боюсь, что стандартными линкерами тут не обойдешься. MS>Ведь линкер должен будет создать запись в таблице импорта и заглушки (корректируеются при загрузке библиотеки по конкретному адресу), для этого нормальному линкеру и нужна библиотека импорта (от пользователя) и список используемых функций (от компилятора).
Жаль что нет средств для того, чтобы прагмами или опциями линкера сымитировать линковку с libой от нужной DLLки.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, MShura, Вы писали:
CC>>>Кстати любопытный вопрос: можно ли статически связать свою прогу с чужой DLL (к примеру, подцепить NtQueryInformationFile из ntdll.dll) не имея к ней lib и не создавая для этого фейковый lib.
MS>>Боюсь, что стандартными линкерами тут не обойдешься. MS>>Ведь линкер должен будет создать запись в таблице импорта и заглушки (корректируеются при загрузке библиотеки по конкретному адресу), для этого нормальному линкеру и нужна библиотека импорта (от пользователя) и список используемых функций (от компилятора).
CC>Жаль что нет средств для того, чтобы прагмами или опциями линкера сымитировать линковку с libой от нужной DLLки.
Спасибо за отзывы, но руки у меня оказались слишком кривые:
Я второпях забыл подключить lib-файл к проекту , так что задачка даже ещё хуже оказалась
Есть только lib файл Delphi (не знаю какой именно версии, или 5-ой или 7-ой, скорее всего) и сама dll.
Когда его подключил выдалась ошибка
"fatal error LNK1107: invalid or corrupt file: cannot read at 0x310 e:\Prg\temp\110706\Import\exdpr.lib",
если подключаю в проект lib-файл, с определением
Здравствуйте, MShura, Вы писали:
FDS>>Да, а вот в Delphi — легко!
MS>Можно подробней? MS>DLL загружается загрузчиком PE или все-же самим приложением?
MS>В VC можно воспользоваться таким вариантом "отложенной" загрузки MS>http://www.rsdn.ru/article/cpp/delayload.xml
Я не знаю как она загружается , если нужно, могу посмотреть в дизассемблере
Важно то, что для программиста это выглядит как статический импорт со всеми удобствами, а динамический импорт реализуется явно как вызовы API — что не так удобно.
MS>>Можно подробней? MS>>DLL загружается загрузчиком PE или все-же самим приложением?
MS>>В VC можно воспользоваться таким вариантом "отложенной" загрузки MS>>http://www.rsdn.ru/article/cpp/delayload.xml
FDS>Я не знаю как она загружается , если нужно, могу посмотреть в дизассемблере
Достаточно посмотреть dependecies исполняемого файла или dumpbin /imports your.exe.
Будет ли среди импортных dll ваша dll.
Если будет, то эту dll загрузит загрузчик файла
FDS>Важно то, что для программиста это выглядит как статический импорт со всеми удобствами, а динамический импорт реализуется явно как вызовы API — что не так удобно.
Как программа будет себя вести, если:
— не найдет нужной dll
— не найдет нужной функции в dll
Насколько я понял автора топика он пытался использовать dll скомпиленную не по правилам MS, как если бы она была таковой.
Естественно получил проблему.
То что Дельфи знает формат MS ( иначе она не смогла бы компилиться с kernel32.lib ) это конечно хорошо, но должна ли MS знать формат Дельфи?
Здравствуйте, MShura, Вы писали:
MS>>>Можно подробней? MS>>>DLL загружается загрузчиком PE или все-же самим приложением?
MS>>>В VC можно воспользоваться таким вариантом "отложенной" загрузки MS>>>http://www.rsdn.ru/article/cpp/delayload.xml
FDS>>Я не знаю как она загружается , если нужно, могу посмотреть в дизассемблере
MS>Достаточно посмотреть dependecies исполняемого файла или dumpbin /imports your.exe. MS>Будет ли среди импортных dll ваша dll. MS>Если будет, то эту dll загрузит загрузчик файла
Например, import.exe использует функцию EX из exdpr.dll:
dumpbin /imports import.exe.
...
exdpr.dll
40B214 Import Address Table
0 Import Name Table
0 time date stamp
0 Index of first forwarder reference
0 EX
...
Смотрел своим просмотрщиком — то же говорит, что есть в секции импорта
MS>Как программа будет себя вести, если: MS>- не найдет нужной dll
Диалог при запуске (до исполнения какого-либо кода, даже если он не относится к импортируемым функиям)
---------------------------
Import.exe — Не удалось найти компонент
---------------------------
Приложению не удалось запуститься, поскольку exdpr.dll не был найден. Повторная установка приложения может исправить эту проблему.
---------------------------
ОК
---------------------------
MS>- не найдет нужной функции в dll
Диалог при запуске
---------------------------
Import.exe — Точка входа не найдена
---------------------------
Точка входа в процедуру _EX@4 не найдена в библиотеке DLL exdpr.dll.
---------------------------
ОК
---------------------------
MS>Насколько я понял автора топика он пытался использовать dll скомпиленную не по правилам MS, как если бы она была таковой. MS>Естественно получил проблему. MS>То что Дельфи знает формат MS ( иначе она не смогла бы компилиться с kernel32.lib ) это конечно хорошо, но должна ли MS знать формат Дельфи?
Не. Не так. Delphi не знает формат MS! Delphi знает как только генерировать PE-файл.
В секции импорта PE-файла пишется название dll и имя импортируемой функции и всё. Остальное делает загрузчик Windows.
То есть Delphi никаких lib-файлов не требуется. Я могу импортировать функцию из любой dll, если знаю её имя или индекс, название dll и соглашение о вызове (и сигнатуру). То есть, если я хочу импортировать функцию EX из exdpr.dll, но при этом она скомпилирована MS VC с модификаторами extern "C" и __stdcall то мне нужно написать строку
function EX(var Data: integer): integer; stdcall; external'exdpr.dll' name '_EX@4';
и больше ничего не надо, кроме файла exdpr.dll во время исполнения в надлежащей директории.
MS должна позволять импортировать функции независимо от того, кто скомпилировал dll — Delphi это позволяет. Странно что MS — нет. Я был очень удивлён, но сам ничего в справке не нашёл по этому поводу.
Здравствуйте, Ракопаукодав, Вы писали:
Р>Спасибо за отзывы, но руки у меня оказались слишком кривые:
Р>Я второпях забыл подключить lib-файл к проекту , так что задачка даже ещё хуже оказалась
Р>Есть только lib файл Delphi (не знаю какой именно версии, или 5-ой или 7-ой, скорее всего) и сама dll.
Р>Когда его подключил выдалась ошибка Р>"fatal error LNK1107: invalid or corrupt file: cannot read at 0x310 e:\Prg\temp\110706\Import\exdpr.lib", Р>если подключаю в проект lib-файл, с определением Р>
Р>скомпилированный на C++ — то всё нормально, но у меня такого файла на самом деле нет.
Р>В общем, чую придётся использовать динамический импорт , как подсказывали выше
Р>Я НЕ могу перекомпилировать dll — она из другой фирмы и у меня нет исходных кодов.
По идее, если всё-таки попросить ребят перекомпилировать dll с декорированными именами, lib-файл можно создать путём компиляции "пустой" dll с такими же функциями.
То есть компилишь dll-ку с функцией EX, в которой есть одна строка — return 0; на C++
Перекомпилируешь реальную dll с функцией EX на функцию _EX@4
Компилишь своё приложение с подложным lib-файлом и подкладываешь реальную dll с изменёнными вариантами