lapulya
Молодой специалист
Offline
|
|
« : 12-11-2010 12:04 » |
|
Хочу чтобы связывание происходило в момент загрузки dll, конкретно нужно вот, что:
Есть dll, в ней объявлена и используется внешняя функция/переменная, которая определяется в exe, которое и грузит данную dll. Говорят в linux это делается на раз, как это сделать в windows? Если можно ссылку на описание + пример (exe с одной функцией и dll которая использует на MS VC), ну или описание того, что в windows этого механизма нет.
|
|
|
Записан
|
С уважением Lapulya
|
|
|
zubr
Гость
|
|
« Ответ #1 : 12-11-2010 13:00 » |
|
1. В dll определяешь функцию, к примеру назовем void FuncExeLoader(CMyExeFuncPointer pMyExeFunc); Данная функция просто получает указатель на функцию из exe. 2. В exe загружаешь dll и вызываешь функцию dll FuncExeLoader с указателем на функцию exe MyExeFunc. 3. В dll вызываешь внешнюю функцию MyExeFunc.
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #2 : 12-11-2010 13:17 » |
|
Нееее это корявый воркэрраунд, а я спрашиваю про нормальный линкинг. Т.е. в линуксе, как я понял можно указать, что данная функция определена вне библиотеки, после чего можно собрать библиотеку и линкер не будет орать, что у него нет определения этой функции. При лоаде библиотки происходит связывание и все работает как должно.
Хочу вот именно так.
Добавлено через 2 часа, 46 минут и 19 секунд: Народ! Помогите, плз очень надо! Не хочется при портировании с Linux тучу чужого кода перелопачивать...
|
|
« Последнее редактирование: 12-11-2010 16:04 от lapulya »
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #3 : 12-11-2010 19:21 » |
|
А содержит ли PE EXE формат символы для экспорта?
Добавлено через 1 минуту и 40 секунд: lapulya, предлагаю такой подход: создаешь структуру с указателями на функции и передаешь ее в подгружаемые модули.
|
|
« Последнее редактирование: 12-11-2010 19:23 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #4 : 12-11-2010 19:44 » |
|
))) Еще раз, мне НЕ нуже воркэраунд.
Давайте еще уточню, дело в том что есть некоторый набор программ и утилит (несколько, более 10, exe + на винде будут писаться еще exe), они юзают еще большее кол-во dll, причем некоторые dll являются различными реализациями одних и тех же интерфейсов (интерфейс в данном случае это не класс с++, а набор классов/функций/переменных/протоколов обмена и т.д.). Это все уже написано и работает на Linux, надо чтоб заработало на винде. При этом если можно сделать указанный финт с вынесенной реализацией внешних функций библиотеки, то дело решается настройками среды (что собственно очень хочется), а не реинжинирингом кода. Понятно, что если это в винде сделать нельзя, я пока не могу найти как это сделать, то придется это обходить. При этом, четкой инфы, что этого в винде сделать нельзя, я тоже не нашел...
Весь указанный код на половину чужой и рабочий, менять его очень не хочется.
Ясно что можно придумать кучу методов обхода, в том числе и просто передать в dll поинтер на согласованный абстрактный класс, реализация наследника которого в exe, это все ясно, но это требует изменений в исходном коде, а я хочу этого избежать.
Большое спасибо, что пытаетесь помочь, но пока не много не то, жду еще предложений именно по той схеме, что я изложил в начале (без переделки кода).
|
|
« Последнее редактирование: 12-11-2010 19:48 от lapulya »
|
Записан
|
С уважением Lapulya
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 12-11-2010 19:51 » |
|
lapulya, включи в дистрибутив программы установку виртуального линукса
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #6 : 12-11-2010 20:53 » |
|
Леш, я сейчас тоже самое хотел предложить, но увидел твой пост. Присоединяюсь!
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Антон (LogRus)
|
|
« Ответ #7 : 13-11-2010 07:02 » |
|
lapulya, давай по порядку. 1. Винда разрешает собрать dll с неразрешенными зависимостями? 2. Почему бы не использовать GCC на винде?
Почему это работает в линухе? потому, что это свойство не столько линковщика, сколько загрузчика Elf, но лично я не вижу причин почему бы загрузчику PE не работать также.
|
|
|
Записан
|
Странно всё это....
|
|
|
Chaa
|
|
« Ответ #8 : 13-11-2010 10:51 » |
|
В виндовс это называется delayload. В разных компиляторах это сделано по-разному. Для Visual C++ вы просто указываете компоновщику опцию /delayload:mydll. Также необходимо подключить библиотеку Delayimp.lib, в ней находится код отложенной загрузки DLL. При первом вызове функции библиотека будет загружена, функция в ней найдена и вместо адреса заглушки подставлен адрес нужной функции. Если загрузить библиотеку не удастся, будет выброшено исключение (SEH, см. RaiseException в Platform SDk).
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #9 : 14-11-2010 03:02 » |
|
Спасибо, завтра пойду пробовать, щпа ваще не вдупляю, т.к. оч. сильно пьян. орри за небольшой оффтоп
|
|
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #10 : 14-11-2010 10:39 » |
|
Chaa, "ленивая загрузка" в Linux используется не для загрузки библиотек, а наоборот - при динамической (не автоматической! - см. dlopen()) загрузке библиотек и автоматического разрешения внешних символов самой загружаемой библиотеки. Причем, искомые символы ищутся в модуле, который грузит эту библиотеку. Например: main.c int main(int argc, char **argv) { /* ... разный код, включая загрузку библиотеки ... */ }
void my_func(void) { /* некий код */ } mylib.c extern int my_func(void);
void lib_func(void) { my_func(); } Загрузчик библиотеки mylib, если ему передать в параметрах флаг ленивой загрузки, найдет в основном модуле my_func.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #11 : 14-11-2010 11:16 » |
|
Ну вот я даже читать могу))). Итак RXL какмне кажется максимально подробно изложил то, что мне нужно. Осталось только сделать это в Винде. Антон (LogRus), 1. Винда разрешает собрать dll с неразрешенными зависимостями? этого я не знаю, я это уже писал При этом если можно сделать указанный финт с вынесенной реализацией внешних функций библиотеки ... я пока не могу найти как это сделать ... При этом, четкой инфы, что этого в винде сделать нельзя, я тоже не нашел...
Почему это работает в линухе? потому, что это свойство не столько линковщика, сколько загрузчика Elf, но лично я не вижу причин почему бы загрузчику PE не работать также. Да, в какой то статье, коих я на эту тему пролистал (они по большей части всеже касаются линукса) было сказано, что это фича именно загрузчика Elf. Я тоже не вижу почему бы этому не работать в винде, но добиться я этого пока не смог )))
|
|
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #12 : 14-11-2010 11:29 » |
|
lapulya, может тебе нужно написать собственный загрузчик библиотек?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #13 : 14-11-2010 12:40 » |
|
))) Шутить я тоже умею... тока пока не смешно... дело то стоит
|
|
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #14 : 14-11-2010 12:43 » |
|
А при чем тут шутки...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #15 : 14-11-2010 14:11 » |
|
А что ты под загрузчиком понимаешь? Удастся ли решить мою проблему (не меняя имеющегося кода, портировать приложения на винду)?
|
|
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #16 : 14-11-2010 14:14 » |
|
Я понимаю некий интерфейс, реализуемый в обеих частях программы, который позволит разрешать символы или использовать принцип stub с набором указателей.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #17 : 14-11-2010 14:16 » |
|
я правильно понимаю, что по сути это то же самое что предложил зубр во втором посте ветки?
|
|
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #18 : 14-11-2010 15:24 » |
|
Думаю, что не совсем.
Вот такая мысль появилась: а нельзя ли указать, что внешние символы импортируются из основного модуля? Ведь указаны же в таблице импорта PE имена библиотек.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #20 : 14-11-2010 15:49 » |
|
RXL, Еще одна идея: вынести функции, с которыми работают подгружаемые библиотеки, в отдельную DLL. Это и планировалось сделать, если не будет найдено решения с стиле "ставим галку все работает". Только линковать библиотеку будем статически (бум делать lib, а не dll) так будет меньше вмешательство в код.
|
|
« Последнее редактирование: 14-11-2010 15:52 от lapulya »
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #21 : 14-11-2010 17:27 » |
|
lapulya, вот потому я и не люблю винду: можно сделать многое, но усилия не соразмерны.
Что скажешь о идее в посте №18?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|
Chaa
|
|
« Ответ #23 : 16-11-2010 15:38 » |
|
Еще одна идея: вынести функции, с которыми работают подгружаемые библиотеки, в отдельную DLL.
Это наиболее практичный способ. Вместо Delayimp.lib вы можете написать свой обработчик, который будет искать delayload-функции в нужном вам месте. Например, можно просматривать секцию экспорта в главном PE-файле, и искать там функции (видимо нужно как-то сказать компоновщику, чтобы там была таблица экспорта). Т.е. в подключаемой вами библиотеке функции будут объявлены как delayload. При первом вызове такой функции будет вызван ваш код поиска тела функции, и тут уже можно что-то реализовать.
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #24 : 16-11-2010 15:56 » |
|
А каким образом получить доступ к PE приложения из загрузчика dll? Стандартно необходимо явно указать модуль из которого необходимо производить импорт (например user32.dll), а что указывать при обращении к загруЖАЮЩЕМУ модулю? В гугле нарыть этого не смог.
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Chaa
|
|
« Ответ #25 : 16-11-2010 16:46 » |
|
EXE-файл загружается всегда по одному и тому же виртуальному адресу, т.е. вы всегда знаете его HISNTANCE (что-то вроде 0x00400000).
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #26 : 16-11-2010 18:04 » |
|
))) это понятно, но: 1) это хардкор 2) ну а если это не exe, а другая dll, тогда что?
|
|
|
Записан
|
С уважением Lapulya
|
|
|
RXL
|
|
« Ответ #27 : 16-11-2010 18:06 » |
|
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|