Russian Qt Forum
Ноябрь 24, 2024, 10:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 3 [4] 5 6 7   Вниз
  Печать  
Автор Тема: [4.3.0-win] Как быть с dll?  (Прочитано 53455 раз)
Icoz
Гость
« Ответ #45 : Август 14, 2007, 12:28 »

Цитата: "Alex Forth"
Для эксперимента была взята первая попавшаяся dll из c:/windows/system32 ею оказалась ALut.dll.

А она делфевая? Ну или хотя бы билдеровская? Кароче Borland?
Цитата: "Alex Forth"

Код:

alutExit@0 =  alutExit @3
alutInit@0 = alutInit @3


Это у тебя ординалы в обоих функциях в конце стоят? Если да, то почему одинаковые для разных функций?
Цитата: "Alex Forth"

Код:
extarn "C" __stdcall void alutInit();


А вот это надо проверить... Хотя... Мне же он ругается не на какой-нибудь аккес-виолейшн, а на то, что так и пытается найти имя типа alutExit@0 вместо alutExit (по твоему примеру, у себя я эту dll не пробовал...) Ты лучше класс какой-нибудь так попробуй подгрузить! Там такие красивые имена!!!
ЗЫ. Кстати, напиши, каким компилятором ты пользуешься! У меня mingw идущий с dev-cpp, обновленный из его же репов. кутя 4.3.0 (хоть это и не важно, ибо трабла gcc) Приду домой, еще и версию gcc напишу... Улыбающийся
Записан
Alex Forth
Гость
« Ответ #46 : Август 14, 2007, 14:40 »

Цитата: "Icoz"

А она делфевая? Ну или хотя бы билдеровская? Кароче Borland?

Єто не важно. Главное, что там STDCALL.

Цитата: "Icoz"

Это у тебя ординалы в обоих функциях в конце стоят? Если да, то почему одинаковые для разных функций?

 :oops:  Ты прав - ординалы надо было сделать разными.

Цитата: "Icoz"

А вот это надо проверить... Хотя... Мне же он ругается не на какой-нибудь аккес-виолейшн, а на то, что так и пытается найти имя типа alutExit@0 вместо alutExit (по твоему примеру, у себя я эту dll не пробовал...) Ты лучше класс какой-нибудь так попробуй подгрузить! Там такие красивые имена!!!
ЗЫ. Кстати, напиши, каким компилятором ты пользуешься! У меня mingw идущий с dev-cpp, обновленный из его же репов. кутя 4.3.0 (хоть это и не важно, ибо трабла gcc) Приду домой, еще и версию gcc напишу... Улыбающийся

У меня gcc 3.4.2. Траблов ни в моем ни в твоем нет, я в этом уверен.
Проблема в том, как именуются функции внутри dll, библиотеки импорта и внутри твоих обьектніх файлов. Как только во всех перечисленніх местах имена будут одни и теже, все заработает Улыбающийся
Записан
Icoz
Гость
« Ответ #47 : Август 14, 2007, 21:02 »

как только имена одни и те же, то у меня все собирается, но не запускается. см выше

добавлено спустя 4 часа 32 минуты:

 У меня gcc 3.4.2 mingw-(special). проверил и твой вариант с ординалами.
Код:
mapCloseMap@4 = mapCloseMap @2364

В результате он все равно ищет при запуске mapCloseMap@4
Записан
Icoz
Гость
« Ответ #48 : Август 23, 2007, 14:24 »

поднимаю вопрос наверх. Проблема так и не решена.
Пока делаю временную хрень типа враппера. Почти готово, только дикий гемор, ибо там между классами стремные связи.
КАК СДЕЛАТЬ IMPORT LIB ДЛЯ gcc?
« Последнее редактирование: Сентябрь 07, 2007, 15:08 от Icoz » Записан
Alex Forth
Гость
« Ответ #49 : Сентябрь 04, 2007, 20:21 »

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

Первым делом я заюзал утилитку pexports
Код:
pexports -o mapacces.dll > mapacces.def
В полученном def файле все имена функций и методов выглядят довольно страшно. Так функция char* Ansi2Dos(char*, int) называется не иначе как @Ansi2Dos$qpci. Конструктор TBaseColors::TBaseColors(), как @TBaseColors@$bctr$qv. Такое искажение - это внутрений стандарт borland по именованию функций/методов. gcc неспособен такое переварить и посему, нам надо подправить полученный def файл на предмет алиасов. Так для char* Ansi2Dos(char*, int)  алиас будет выглядеть так: Ansi2Dos = @Ansi2Dos$qpci         @1
для TBaseColors::TBaseColors()  -> _imp___ZN11TBaseColorsC1Ev=@TBaseColors@$bctr$qv      @6

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

Библиотека импорта изготавливается с помощью команды:
Код:
dlltool  -llibaccesmap.a -Dmapacces.dll -dmapacces.def

Теперь к хидерам. Их прийдется немного поправить.
Так для функции char* Ansi2Dos(char*, int)  декларация должна выглядеть так: extern "C" char* Ansi2Dos(char*, int);
Вообщето можно обойтись и без extern "C" , но тогда прийдется использовать __attribute__ ((dllimport)), речь о котором будет ниже, и алиас к этой функции будет уже не таким наглядным.
Для класса есть 2 формы записи. Первая выглядит так:
Код:
class __attribute__ ((dllimport)) TBaseColors 
{
  .....
  .....
  .....
}
Это более краткая форма, но если в классе есть inline методы, то ничего не выйдет.
Второй вариант заключается в использовании __attribute__ ((dllimport)) в декларации каждого метода. В этом случае получится что-то вроде этого:
Код:
class  TBaseColors 
{
 public:
        TBaseColors()__attribute__ ((dllimport));
TBaseColors(unsigned long*, int)__attribute__ ((dllimport));
~TBaseColors(){};
void BuildColors()__attribute__ ((dllimport));
void InitBaseColors(unsigned long*, int)__attribute__ ((dllimport));
void SetBright(int)__attribute__ ((dllimport));
void SetColor(unsigned long,int)__attribute__ ((dllimport));
void SetColorStyle(int)__attribute__ ((dllimport));
void SetContrast(int)__attribute__ ((dllimport));
void SetNonlinearBright(int)__attribute__ ((dllimport));
}


И под конец,  __attribute__ ((dllimport))  желательно заменить на более "стандартный" макрос DECL_IMPORT (см. хидеры от mingw).


« Последнее редактирование: Сентябрь 04, 2007, 20:28 от Alex Forth » Записан
Разуев Максим
Гость
« Ответ #50 : Сентябрь 05, 2007, 08:06 »

Кстати из dll можно получить класс. Для этого в нормальных dll-ках должна быть функция get_interface. Тогда имея виртуальный класс описанный в хидере и получив интерфейс можно работать с dll.
Записан
vaprele07
Гость
« Ответ #51 : Сентябрь 05, 2007, 09:58 »

Alex Forth
как у тебя осуществляется связь с thisObject (Дескриптор объекта) Строит глазки ведь все остальные, кроме конструктора, функции должны знать!. где лежит ихний родитель?

и вызов функции выглядит типа того:  SetNonlinearBright(thisObject, int).

Есть такая штука DeDe, помнится она красиво и наглядно импортировала дэльфевые классы.
Записан
Alex Forth
Гость
« Ответ #52 : Сентябрь 05, 2007, 11:26 »

Цитировать
Alex Forth
как у тебя осуществляется связь с thisObject (Дескриптор объекта)  ведь все остальные, кроме конструктора, функции должны знать!. где лежит ихний родитель?
Давай попорядку. Есть класс, а есть екземпляр класса. Каждый не static метод класса должен получать указатель на экземпляр класса, с которым он должен работать. Ты это имел ввиду?

Создание экземпляра можно разделить на 2 этапа:
1) Выделение памяти - этим занимается компилятор ( точнее стандартный менеджер памяти, но в данный момент это не важно) и для этого ему надо знать только размер экземпляра.
2) Инициализация выделенной памяти - этим занимается конструктор
Размер экземпляра можно поределить только по его хидеру.
Вся цепочка наследований нужна только приведения указателей/ссылок и тоже берется из хидеров.

Цитировать
и вызов функции выглядит типа того:  SetNonlinearBright(thisObject, int).
Так написать без танцев с бубном крайне проблематично, поскольку способ передачи аргументовдля методов и для обыкновенных функций отличается. У меня использования класса выглядит, как обычно.

ЗЫ: Только что понял - я забыл протестировать импорт виртуальных методов. Там должны быть свои сюрпризы  Смеющийся
Записан
Icoz
Гость
« Ответ #53 : Сентябрь 05, 2007, 21:56 »

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

Код:
pexports -o mapacces.dll > mapacces.def
Ansi2Dos = @Ansi2Dos$qpci      @1
dlltool  -llibaccesmap.a -Dmapacces.dll -dmapacces.def
Я такое делал. Не помогло. Выходит под mingw надо хидеры править...

Код:
TBaseColors::TBaseColors()  -> _imp___ZN11TBaseColorsC1Ev=@TBaseColors@$bctr$qv   	@6
А как мне можно более-менее эффективно составить список названий типа _imp___ZN11TBaseColorsC1Ev? Простые функции - еще ладно, а как попроще такие вот кракозябры для классов сгенерить. Сам видел, что там строк 3500!
И для каждой функции класса смотреть по выводу gcc, что не найдена функция "_imp___ZN11TBaseColorsC1Ev" - жестоко! Грустный

Теперь к хидерам. Их прийдется немного поправить.
Так для функции char* Ansi2Dos(char*, int)  декларация должна выглядеть так: extern "C" char* Ansi2Dos(char*, int);
Ну у меня все хидеры так завернуты. У каждого по extern "C" {...}. Но у меня не пашет.

Вообщето можно обойтись и без extern "C" , но тогда прийдется использовать __attribute__ ((dllimport)), речь о котором будет ниже, и алиас к этой функции будет уже не таким наглядным.
Для класса есть 2 формы записи. Первая выглядит так:
Код:
class __attribute__ ((dllimport)) TBaseColors 
{
  .....
  .....
  .....
}
Это более краткая форма, но если в классе есть inline методы, то ничего не выйдет.
Они есть! Грустный

Второй вариант заключается в использовании __attribute__ ((dllimport)) в декларации каждого метода. В этом случае получится что-то вроде этого:
Код:
class  TBaseColors 
{
 public:
        TBaseColors()__attribute__ ((dllimport));
TBaseColors(unsigned long*, int)__attribute__ ((dllimport));
        ...
void SetNonlinearBright(int)__attribute__ ((dllimport));
}

И под конец,  __attribute__ ((dllimport))  желательно заменить на более "стандартный" макрос DECL_IMPORT (см. хидеры от mingw).
то есть заменить? Небольшой кусок кода дай, как оно должно выглядеть в заменненом варианте...
Записан
Icoz
Гость
« Ответ #54 : Сентябрь 05, 2007, 22:17 »

Есть такая штука DeDe, помнится она красиво и наглядно импортировала дэльфевые классы.
Что-то я такую прогу в нете не нашел. Название поточнее не помните?
Записан
vaprele07
Гость
« Ответ #55 : Сентябрь 06, 2007, 06:05 »

http://reversing.kulichki.ru/files/dizas/DeDe.rar
Записан
Alex Forth
Гость
« Ответ #56 : Сентябрь 06, 2007, 09:55 »

Цитировать
то есть заменить? Небольшой кусок кода дай, как оно должно выглядеть в заменненом варианте...

Все просто Улыбающийся
Вместо __attribute__ ((dllimport)) пиши DECL_IMPORT
Записан
Icoz
Гость
« Ответ #57 : Сентябрь 06, 2007, 15:06 »

Повторюсь, но сие очень важно:

Код:
TBaseColors::TBaseColors()  -> _imp___ZN11TBaseColorsC1Ev=@TBaseColors@$bctr$qv   	@6
А как мне можно более-менее эффективно составить список названий типа _imp___ZN11TBaseColorsC1Ev? Простые функции - еще ладно, а как попроще такие вот кракозябры для классов сгенерить. Alex Forth видел, что там строк около 3500!
И для каждой функции класса смотреть по выводу gcc, что не найдена функция "_imp___ZN11TBaseColorsC1Ev" - жестоко! Грустный

У кого есть идеи как по симпатичнее достать все эти замангленные имена? Писать скрипт, который по аргументам соберет нужное имя - отпадает, ибо задачка не слишком тривиальная... Грустный
Записан
Icoz
Гость
« Ответ #58 : Сентябрь 07, 2007, 15:10 »

DeDe мою библиотеку не кушает. Она не делфевая, а просто борландовская. Скорее всего borland c++ 5.02 (старый, еще до билдера)
Записан
vaprele07
Гость
« Ответ #59 : Сентябрь 07, 2007, 15:47 »

так скачай новую версию либы, я там посмотрел у них даже qt проскакивает, за общайся с авторами... может они тебе помогут?
Записан
Страниц: 1 2 3 [4] 5 6 7   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.056 секунд. Запросов: 21.