Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: lazy linking (binding)  (Прочитано 24261 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
lapulya
Молодой специалист

ru
Offline 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
Молодой специалист

ru
Offline Offline

« Ответ #2 : 12-11-2010 13:17 » 

Нееее это корявый воркэрраунд, а я спрашиваю про нормальный линкинг. Т.е. в линуксе, как я понял можно указать, что данная функция определена вне библиотеки, после чего можно собрать библиотеку и линкер не будет орать, что у него нет определения этой функции. При лоаде библиотки происходит связывание и все работает как должно.

Хочу вот именно так.

Добавлено через 2 часа, 46 минут и 19 секунд:
Народ! Помогите, плз очень надо! Не хочется при портировании с Linux тучу чужого кода перелопачивать...
« Последнее редактирование: 12-11-2010 16:04 от lapulya » Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 12-11-2010 19:21 » 

А содержит ли PE EXE формат символы для экспорта?

Добавлено через 1 минуту и 40 секунд:
lapulya, предлагаю такой подход: создаешь структуру с указателями на функции и передаешь ее в подгружаемые модули.
« Последнее редактирование: 12-11-2010 19:23 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #4 : 12-11-2010 19:44 » 

))) Еще раз, мне НЕ нуже воркэраунд.

Давайте еще уточню, дело в том что есть некоторый набор программ и утилит (несколько, более 10, exe + на винде будут писаться еще exe), они юзают еще большее кол-во dll, причем некоторые dll являются различными реализациями одних и тех же интерфейсов (интерфейс в данном случае это не класс с++, а набор классов/функций/переменных/протоколов обмена и т.д.). Это все уже написано и работает на Linux, надо чтоб заработало на винде. При этом если можно сделать указанный финт с вынесенной реализацией внешних функций библиотеки, то дело решается настройками среды (что собственно очень хочется), а не реинжинирингом кода. Понятно, что если это в винде сделать нельзя, я пока не могу найти как это сделать, то придется это обходить. При этом, четкой инфы, что этого в винде сделать нельзя, я тоже не нашел...

Весь указанный код на половину чужой и рабочий, менять его очень не хочется.

Ясно что можно придумать кучу методов обхода, в том числе и просто передать в dll поинтер на согласованный абстрактный класс, реализация наследника которого в exe, это все ясно, но это требует изменений в исходном коде, а я хочу этого избежать.

Большое спасибо, что пытаетесь помочь, но пока не много не то, жду еще предложений именно по той схеме, что я изложил в начале (без переделки кода).
« Последнее редактирование: 12-11-2010 19:48 от lapulya » Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 12-11-2010 19:51 » 

lapulya, включи в дистрибутив программы установку виртуального линукса Улыбаюсь
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 12-11-2010 20:53 » 

Леш, я сейчас тоже самое хотел предложить, но увидел твой пост. Присоединяюсь!
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 13-11-2010 07:02 » 

lapulya, давай по порядку.
1. Винда разрешает собрать dll с неразрешенными зависимостями?
2. Почему бы не использовать GCC на винде?

Почему это работает в линухе? потому, что это свойство не столько линковщика, сколько загрузчика Elf, но лично я не вижу причин почему бы загрузчику PE не работать также.
Записан

Странно всё это....
Chaa
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 13-11-2010 10:51 » 

В виндовс это называется delayload.
В разных компиляторах это сделано по-разному. Для Visual C++ вы просто указываете компоновщику опцию /delayload:mydll. Также необходимо подключить библиотеку Delayimp.lib, в ней находится код отложенной загрузки DLL.
При первом вызове функции библиотека будет загружена, функция в ней найдена и вместо адреса заглушки подставлен адрес нужной функции.
Если загрузить библиотеку не удастся, будет выброшено исключение (SEH, см. RaiseException в Platform SDk).
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #9 : 14-11-2010 03:02 » 

Спасибо, завтра пойду пробовать, щпа ваще не вдупляю, т.к. оч. сильно пьян. орри за небольшой оффтоп
Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 14-11-2010 10:39 » 

Chaa, "ленивая загрузка" в Linux используется не для загрузки библиотек, а наоборот - при динамической (не автоматической! - см. dlopen()) загрузке библиотек и автоматического разрешения внешних символов самой загружаемой библиотеки. Причем, искомые символы ищутся в модуле, который грузит эту библиотеку.

Например:

main.c
Код: (C)
int main(int argc, char **argv)
{
    /* ... разный код, включая загрузку библиотеки ... */
}

void my_func(void)
{
    /* некий код */
}

mylib.c
Код: (C)
extern int my_func(void);

void lib_func(void)
{
    my_func();
}

Загрузчик библиотеки mylib, если ему передать в параметрах флаг ленивой загрузки, найдет в основном модуле my_func.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #11 : 14-11-2010 11:16 » 

Ну вот я даже читать могу))).

Итак RXL какмне кажется максимально подробно изложил то, что мне нужно. Осталось только сделать это в Винде.

Антон (LogRus),
Цитата
1. Винда разрешает собрать dll с неразрешенными зависимостями?

этого я не знаю, я это уже писал

Цитата
При этом если можно сделать указанный финт с вынесенной реализацией внешних функций библиотеки ... я пока не могу найти как это сделать ... При этом, четкой инфы, что этого в винде сделать нельзя, я тоже не нашел...

Цитата
Почему это работает в линухе? потому, что это свойство не столько линковщика, сколько загрузчика Elf, но лично я не вижу причин почему бы загрузчику PE не работать также.

Да, в какой то статье, коих я на эту тему пролистал (они по большей части всеже касаются линукса) было сказано, что это фича именно загрузчика Elf. Я тоже не вижу почему бы этому не работать в винде, но добиться я этого пока не смог )))
Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 14-11-2010 11:29 » new

lapulya, может тебе нужно написать собственный загрузчик библиотек? Улыбаюсь
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #13 : 14-11-2010 12:40 » 

))) Шутить я тоже умею... тока пока не смешно... дело то стоит
Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 14-11-2010 12:43 » 

А при чем тут шутки...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #15 : 14-11-2010 14:11 » 

А что ты под загрузчиком понимаешь? Удастся ли решить мою проблему (не меняя имеющегося кода, портировать приложения на винду)?
Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 14-11-2010 14:14 » 

Я понимаю некий интерфейс, реализуемый в обеих частях программы, который позволит разрешать символы или использовать принцип stub с набором указателей.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #17 : 14-11-2010 14:16 » 

я правильно понимаю, что по сути это то же самое что предложил зубр во втором посте ветки?
Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 14-11-2010 15:24 » 

Думаю, что не совсем.

Вот такая мысль появилась: а нельзя ли указать, что внешние символы импортируются из основного модуля? Ведь указаны же в таблице импорта PE имена библиотек.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 14-11-2010 15:39 » 

http://msdn.microsoft.com/ru-ru/library/h90dkhs0%28v=VS.90%29.aspx
Еще одна идея: вынести функции, с которыми работают подгружаемые библиотеки, в отдельную DLL.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #20 : 14-11-2010 15:49 » 

RXL,
Цитата
Еще одна идея: вынести функции, с которыми работают подгружаемые библиотеки, в отдельную DLL.
Это и планировалось сделать, если не будет найдено решения с стиле "ставим галку все работает". Только линковать библиотеку будем статически (бум делать lib, а не dll) так будет меньше вмешательство в код.
« Последнее редактирование: 14-11-2010 15:52 от lapulya » Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #21 : 14-11-2010 17:27 » 

lapulya, вот потому я и не люблю винду: можно сделать многое, но усилия не соразмерны.

Что скажешь о идее в посте №18?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #22 : 14-11-2010 21:45 » 

RXL,
Цитата
а нельзя ли указать, что внешние символы импортируются из основного модуля? Ведь указаны же в таблице импорта PE имена библиотек

А как это сделать? Да и потом, откудаж dll знает кто ее будет грузить? Т.е. можно указать имена функций, а вот как указать откуда их брать?

Вот что-то интересное, но примера нет, есть только теория, из которой не понятен принцип реализации
http://www.symantec.com/connect/articles/dynamic-linking-linux-and-windows-part-two

и тут интересно
http://www.wasm.ru/article.php?article=win32appbyhand

пойду копаться
« Последнее редактирование: 14-11-2010 21:53 от lapulya » Записан

С уважением Lapulya
Chaa
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 16-11-2010 15:38 » 

Еще одна идея: вынести функции, с которыми работают подгружаемые библиотеки, в отдельную DLL.
Это наиболее практичный способ.

Вот что-то интересное, но примера нет, есть только теория, из которой не понятен принцип реализации
http://www.symantec.com/connect/articles/dynamic-linking-linux-and-windows-part-two
Вместо Delayimp.lib вы можете написать свой обработчик, который будет искать delayload-функции в нужном вам месте. Например, можно просматривать секцию экспорта в главном PE-файле, и искать там функции (видимо нужно как-то сказать компоновщику, чтобы там была таблица экспорта).
Т.е. в подключаемой вами библиотеке функции будут объявлены как delayload. При первом вызове такой функции будет вызван ваш код поиска тела функции, и тут уже можно что-то реализовать.
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #24 : 16-11-2010 15:56 » 

А каким образом получить доступ к PE приложения из загрузчика dll? Стандартно необходимо явно указать модуль из которого необходимо производить импорт (например user32.dll), а что указывать при обращении к загруЖАЮЩЕМУ модулю? В гугле нарыть этого не смог.
Записан

С уважением Lapulya
Chaa
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 16-11-2010 16:46 » 

EXE-файл загружается всегда по одному и тому же виртуальному адресу, т.е. вы всегда знаете его HISNTANCE (что-то вроде 0x00400000).
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #26 : 16-11-2010 18:04 » 

))) это понятно, но:
1) это хардкор
2) ну а если это не exe, а другая dll, тогда что?
Записан

С уважением Lapulya
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #27 : 16-11-2010 18:06 » 

Тогда читай вот это: http://msdn.microsoft.com/ru-ru/library/h90dkhs0%28v=VS.90%29.aspx
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines