Russian Qt Forum

Qt => Общие вопросы => Тема начата: Icoz от Июль 27, 2007, 08:14



Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 08:14
У меня есть dll, в которой объявлены несколько сотен функций и с десяток классов. Есть хидеры к ней.
Вопрос: как из dll сделать lib? Причем так, чтобы его ел mingw(там вроде нужно дополнительное конвертирование *.lib -> *.a)?
Делал так:
Код:
pexport -o my.dll > my.def
dlltool -dmy.def -Dmy.dll -lmy.a -A -p_imp

не помогает. Причем с -p (прописывание алиасов с префиксами) перепробовал по разному! Так хотя бы компилируется (после подправления ручками def-файла), но при запуске пишет, что функция такая-то не найдена по пути "..." и прочее...

PS. Очень хочется подключить данную dll статически, ибо тогда смогу заюзать классы, а не писать их реализацию самому...
PPS. Либо может кто расскажет, как из библиотеки подгрузить класс динамически с помощью QLibrary?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 09:21
Цитата: "Icoz"

PS. Очень хочется подключить данную dll статически, ибо тогда смогу заюзать классы, а не писать их реализацию самому...

DLL статически не подключаются! Файл библиотеки импорта для dll и файл статической библиотеки имеют одинаковые расширения, но на этом их сходство заканчивается.

Цитата: "Icoz"

PPS. Либо может кто расскажет, как из библиотеки подгрузить класс динамически с помощью QLibrary?

Так, как это написанно в хелпе по QLibrary.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 10:20
Цитата: "Alex Forth"
Цитата: "Icoz"

PS. Очень хочется подключить данную dll статически, ибо тогда смогу заюзать классы, а не писать их реализацию самому...

DLL статически не подключаются! Файл библиотеки импорта для dll и файл статической библиотеки имеют одинаковые расширения, но на этом их сходство заканчивается.

Хорошо, объясню иначе.
Функции из dll можно импортировать статически, а можно - динамически!
Статически это подключить lib-ку, а динамически - через LoadMoule и GetProcAddress(для winapi) или через QLibrary! Динамически классы не подрубаются. По крайней мере сколько я не искал по форумам, то так никто подрубить и не смог... :(
А то, про что вы говорите - это динамическая(dll) и статическая(когда библиотека целиком впихивается в exe-шник) линковки.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 10:49
Тогда посмотри доки/примеры по QPluginLoader


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 13:22
Цитата: "Alex Forth"
Тогда посмотри доки/примеры по QPluginLoader

Plugin - это плагин! С ними я хорошо знаком, писал их уже несколько раз. Там идет специальный интерфейс qt, чтобы она могла спокойно все из dll подергать! Такого интерфеса в этой dll нету. Были бы сорцы dll без вопросов их каким-угодно способом подцепил. А так - dll сторонняя, а юзать надо.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 13:31
Можно сделать враппер на основе плагина. Правда тогда будет 2 dll но нужная функциональность будет достигнута.
Дергать напрямую методы из той самой первой dll конечно можно, но мне влом даже описывать все те приседания, которые при этом прийдеться делать.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 13:40
И вообще, народ, вас немного не туда понесло... Это не проблема qt, а скорее mingw

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

 
Цитата: "Alex Forth"
Можно сделать враппер на основе плагина. Правда тогда будет 2 dll но нужная функциональность будет достигнута.
Дергать напрямую методы из той самой первой dll конечно можно, но мне влом даже описывать все те приседания, которые при этом прийдеться делать.

Не понял. Поподробнее, если можно...


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 13:44
Спасибо за множественное число по отношению к моей скромной персоне :)
Это не проблема mingw. Это скорее проблема самих dll. Дело в том, что dll хранит пары:  текстовый ключь - ядрес в памяти. При этом адрес пожет соответствовать переменной, функции, методу класса.... но сразу классу соответствовать не может. Тут разные уровни абстракций - в C++ класс - это неделимая единица, а в dll - это набор методов. Вот по этой причине динамическая загрузка dll с классом сопряжена с многими трудностями.

Цитировать
Не понял. Поподробнее, если можно...

Делаешь класс-посредник, интерфейс которого на все 100% соответствует целевому классу из dll, а с другой стороны этот класс является qt плагином. Dll плагина использует первоначальную dll  классическим методом.

Типа так
Код:

class ClassFromDLL
{
...
public:
int A();
int B();
...
}

class MyWrapper
{
    Q_OBJECT
     Q_INTERFACES(MyWrapperInterface)
  private:
  ClassFromDLL* instance;

public:
 virtual int A()
{
   return instance->A();
};
 virtual int B()
{
   return instance->B();
};

}


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 13:52
Если я правильно понял, то в этом враппере мне все равно надо будет реализовывать функционал тех классов из dll и импортить нужные функции через qlibrary....
Но мне лень. Там большой объем работы! Должен же быть способ для нормального импорта инфы из библиотеки

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

 
Цитата: "Alex Forth"

Делаешь класс-посредник, интерфейс которого на все 100% соответствует целевому классу из dll

То есть. Написать с нуля реализацию класса, пользуясь простыми функциями?
Цитата: "Alex Forth"

а с другой стороны этот класс является qt плагином. Dll плагина использует первоначальную dll  классическим методом.

Как же он тогда ее использует? Скажи этот классический метод и я придумаю, как обойтись без плугина! ;)


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 13:52
Не реализовывать, а вызывать.
Текста конечно много прийдется натоптать :(

Классический метод - это загрузка dll во время старта твоего приложения с помощью загрузчика ситемы. ТОесть это то, от чего ты пытаешся уйти

ЗЫ: если владеешь скриптовыми языками, то можно кодогенератор написать. На входе он будет принимать хидер, с которым поставляется твоя DLL, а на выходе будет выдавать исходники врапера. Это вполне реальная штука. Во врапере весь код однообразен. Непосредственное вмешательство человека потребуется в редких случаях


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 14:11
знаешь, для меня классический метод - это подрубить хидер, в файл *.pro добавить:
LIB += mylib
которая потом станет ключом -lmylib для псс
И ВСЕ!


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 14:18
Цитата: "Icoz"
знаешь, для меня классический метод - это подрубить хидер, в файл *.pro добавить:
LIB += mylib
которая потом станет ключом -lmylib для псс
И ВСЕ!

Именно это я и имел ввиду :)


Название: [4.3.0-win] Как быть с dll?
Отправлено: SABROG от Июль 27, 2007, 14:18
Писал как-то wrapper для mysql dllки, которая была собрана на MSVC, а юзать я ее должен был на BCB. Занятие нудное и долгое. implib помогает не всегда.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 14:20
Цитата: "Alex Forth"

Не реализовывать, а вызывать.

Вот я и спрашиваю, как вызывать? У меня в dll лежит класс, который реализует свою работу на основе сотен функций, которые лежат в ней же.
Динамически через qlibrary я могу вызывать только эти сотни функций, ЗНАЧИТ я должен буду реализовать работу этого класса сам. Более того, мне сильно не улыбается руками писать сотни описаний функций типа:
Код:

typedef struct1* (*myfunc1)(int param1, char * param2);
....
typedef struct1* (*myfuncN)(int param1);


Цитата: "Alex Forth"

Текста конечно много прийдется натоптать :(

ЗЫ: если владеешь скриптовыми языками, то можно кодогенератор написать. На входе он будет принимать хидер, с которым поставляется твоя DLL, а на выходе будет выдавать исходники врапера. Это вполне реальная штука. Во врапере весь код однообразен. Непосредственное вмешательство человека потребуется в редких случаях

Владею, только класс можно генерить, имея какие-то данные, у меня же только дока(в ворде), а как из этой доки выдирать объявления функций я себе плохо представляю. Опять же руками? Тогда и скрипт не нужен... Только если для адаптации.

добавлено спустя 35 секунд:

 
Цитата: "SABROG"
Писал как-то wrapper для mysql dllки, которая была собрана на MSVC, а юзать я ее должен был на BCB. Занятие нудное и долгое. implib помогает не всегда.

ВСВ - это что?

добавлено спустя 45 секунд:

 C++ Builder что ли?


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 14:21
Хидеры для использования dll-ки есть? Без них дело совем плохо.

Плагин с dll-кой связываешь классически. Приложение имеет дело только с плагином.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 14:21
Цитата: "Alex Forth"
Цитата: "Icoz"
знаешь, для меня классический метод - это подрубить хидер, в файл *.pro добавить:
LIB += mylib
которая потом станет ключом -lmylib для псс
И ВСЕ!

Именно это я и имел ввиду :)

Так именно для этого мне и нужен *.lib, из которого делается *.a, который уже линкуется! См. первый пост!


Название: [4.3.0-win] Как быть с dll?
Отправлено: SABROG от Июль 27, 2007, 14:22
Хидеры поставляемые к dllке есть ? Напиши парсер для хидера, который на основе прототипов функций будет выдавать твои:
Код:

typedef struct1* (*myfunc1)(int param1, char * param2);


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


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 14:30
Цитата: "SABROG"
Хидеры поставляемые к dllке есть ? Напиши парсер для хидера, который на основе прототипов функций будет выдавать твои:
Код:

typedef struct1* (*myfunc1)(int param1, char * param2);


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

тоже верно, но хрен с ним с хидерами. Допустим у меня есть файл с описанием прототипов функций и фукция, которая их инициализирует:
Код:
typedef struct1* (*myfunc1)(int param1, char * param2); 
...
myfunc1 func1 = (myfunc1)QLibrary::resolve("my.dll","myfunc1");

Так отлично. Но мою проблему это не решает. Ибо мне на базе этих функций надо будет просто писать свою реализацию класса, который уже есть в dll. Итак, опять вопрос:
КАК ТОГДА ПОДГРУЗИТЬ КЛАСС???
Код:

myclass *cls = (myclass*)QLibrary::resolve("my.dll","myclass::myclass");

не работает.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 14:37
Цитата: "Icoz"
тоже верно, но хрен с ним с хидерами. Допустим у меня есть файл с описанием прототипов функций и фукция, которая их инициализирует:

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

Цитировать
Итак, опять вопрос:
КАК ТОГДА ПОДГРУЗИТЬ КЛАСС???

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


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 14:41
Цитата: "Alex Forth"
Цитата: "Icoz"
тоже верно, но хрен с ним с хидерами. Допустим у меня есть файл с описанием прототипов функций и фукция, которая их инициализирует:

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

Все декларации и прочее - все есть! Дайте код, как запустить конструктор, чтобы получить поинтер на класс! Кто поможет - с меня ПИВО!


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 14:49
Цитата: "Icoz"
Дайте код, как запустить конструктор, чтобы получить поинтер на класс! Кто поможет - с меня ПИВО!


Примерно так:
Код:
void (SomeClass::*my_constructorc_ptr)(int, char*) = QLibrary::resolve("my.dll","void SomeClass::SomeClass(int, char*)");

Только насчет строки "void SomeClass::SomeClass(int, char*)" я не уврен, имена методов в библиотеках очень сильно перекручиваются. Тут надо курить мануал по mangle name

Впрочем один конструктор тебе не поможет.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 27, 2007, 18:37
хм... доеду до дома, попробую. Но когда-то еще на qt4.0-4.1 я пытался так делать, у меня ничего не получилось. Да и в нете тогда по форумам искал, мне сказали, что классы из dll можно получить только подцепив lib.

Итак, а есть у кого мысли по сабжу. Как из dll сделать lib?
ибо я делаю *.a, а при компиляции линкер выводит:
Код:
... unresolved "myfunc1@8" ...

в def правлю строку с
Код:
myfunc1

на
Код:
myfunc1@8

Компилит, но прога при запуске говорит, что функция myfunc1 не найдена в библиотеке my.dll
Пробовал также:
Код:
myfunc1@8 = myfunc1

Тоже не катит

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

 
Цитата: "Alex Forth"
Цитата: "Icoz"
Дайте код, как запустить конструктор, чтобы получить поинтер на класс! Кто поможет - с меня ПИВО!


Примерно так:
Код:
void (SomeClass::*my_constructorc_ptr)(int, char*) = QLibrary::resolve("my.dll","void SomeClass::SomeClass(int, char*)");

Только насчет строки "void SomeClass::SomeClass(int, char*)" я не уврен, имена методов в библиотеках очень сильно перекручиваются. Тут надо курить мануал по mangle name

Впрочем один конструктор тебе не поможет.

Вот строка - это самое главное!
В def'е она лежит как
Код:
@TMapAccess@$bctr@qv

Ни она, ни вариации на тему не работают. Попробовал так:
Код:
	QLibrary lib("mapacces");
QStringList lst;
lst << "@TMapAccess@$bctr$qv";
lst << "TMapAccess::bctr";
lst << "TMapAccess.bctr";
lst << "TMapAccess@$bctr";
lst << "@TMapAccess@ctr@qv";
lst << "@TMapAccess@$bctr@qv";
lst << "TMapAccess@$bctr@qv";
lst << "@TMapAccess@ctr";
lst << "@TMapAccess::ctr";
lst << "TMapAccess@ctr";
lst << "TMapAccess::ctr";
for (int i =0; i<lst.size(); i++){
TMapAccess_constructor map_constr = (TMapAccess_constructor)lib.resolve(lst[i].toAscii().constData());
if (map_constr){
QMessageBox::warning(0,"GOOD",QString("Here is function! %1").arg(i));
return;
}
}
QMessageBox::warning(0,"BAD","There is no function!");

Рад буду узнать любые предложения, как еще попробовать достать конструктор!

добавлено спустя 1 час 39 минут:

 УРА!
Код:
@TMapAccess@$bctr$qv
прокатило!
Только вот кто знает, что возвращает конструктор? Или что ему передавать?
ибо вызывая map_constr у меня в консоли при отладке вылезает
Код:
segmentation fault
in mapacces!@TMapControl@ShowBlockRstDevice$qqrr4TRmf


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 27, 2007, 23:12
Вызывать надо примерно так:
Код:

SomeClass *x = (SomeClass*)malloc( sizeof(SomeClass) );//new некатит т к компилер не может самостоятельно вызвать конструктор
(x->*my_constructor_ptr)(6, "Another arbitrary parameter");//память есть, явн овызываем конструктор.

Остальные методы надо вызывать также.
Деструктор надо вызывать так же и вручную!!!! Автоматом он не вызовется!!! (Ну если он конечно не виртуальный).

ЗЫ: вот классная дока по указателям на методы http://rsdn.ru/article/cpp/fastdelegate.xml?print


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 28, 2007, 17:55
Цитата: "Alex Forth"
Вызывать надо примерно так:
Код:

SomeClass *x = (SomeClass*)malloc( sizeof(SomeClass) );//new некатит т к компилер не может самостоятельно вызвать конструктор
(x->*my_constructor_ptr)(6, "Another arbitrary parameter");//память есть, явн овызываем конструктор.

Остальные методы надо вызывать также.
Деструктор надо вызывать так же и вручную!!!! Автоматом он не вызовется!!! (Ну если он конечно не виртуальный).

ЗЫ: вот классная дока по указателям на методы http://rsdn.ru/article/cpp/fastdelegate.xml?print

Дока классная! Только там не сказано, как указателю на фукцию преобразовать и присвоить значение void*?
Делаю так, не работет:
Код:

//typedef TMapAccess* (TMapAccess::*TMapAccess_ptr)(TMapAccess*);
//typedef void (TMapAccess::*TMapAccess_ptr)(TMapAccess*);
typedef void (TMapAccess::*TMapAccess_ptr)();
//typedef TMapAccess* (TMapAccess::*TMapAccess_ptr)();
...
TMapAccess* map = (TMapAccess*)malloc(sizeof(TMapAccess));
map->*TMapAccess_ptr(); // указатель на функцию-то не установлен!

Как установить указатель?
Так непашет:
Код:

TMapAccess_ptr = (TMapAccess_ptr)lib.resolve("@TMapAccess@$bctr$qv");

говорит, что ему нужна переменная, типа
TMapAccess_ptr - это ТИП.
Кароче, вопрос: как мне к этому указтелю прицепить resolve?

добавлено спустя 21 минуту:

 Судя по доке, должна работать такая вещь:
Код:

1: typedef void (TMapAccess::*TMapAccess_ptr)();
...
2: TMapAccess* map = new TMapAccess();
3: TMapAccess_ptr = &TMapAccess::TMapAccess;
4: map->*TMapAccess_ptr();

1 - объявляю указатель на функцию-член
2 - создаю объект
3 - присваиваю указателю значение (что он должен запускать)
4 - вызываю функцию-член по указателю
Есть НО! Не компилится. Матерится на 3-ю строку:
Код:

 error: expected primary-expression before '=' token
 error: expected primary-expression before ';' token

А по сути:
на второй строке должно быть просто выледение памяти, на третьей - присвоение указателю значения из lib.resolve();
Но я хочу хотя бы так скомпилить, чтобы синтаксис правильный был, а дальше будем усложнять...

добавлено спустя 16 минут:

 Сейчас делаю так(имхо, наиболее логично):
Код:

1: typedef void (TMapAccess::*TMapAccess_ptrTYPE)();
...
2: TMapAccess* map = (TMapAccess*)malloc(sizeof(TMapAccess));
3: TMapAccess_ptrTYPE TMapAccess_ptr = (TMapAccess_ptrTYPE)lib.resolve("@TMapAccess@$bctr$qv");
4: map->*TMapAccess_ptr();

Компилятор ругается:
Код:

3: error: cannot convert `(&lib)->QLibrary::resolve(((const char*)"@TMapAccess@$bctr$qv"))' from type `void*' to type `void (TMapAccess::*)()'
4: error: must use .* or ->* to call pointer-to-member function in `TMapAccess_ptr (...)'

Какие мысли есть?


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 28, 2007, 18:19
Каким компилером пользуешся?


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 28, 2007, 22:08
mingw в винде, разумеется. или тебе версия нужна?

добавлено спустя 32 секунды:

 mingw, который вместе с dev-cpp идет


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 28, 2007, 23:06
попробуй преобразовывать тип с помощью reinterpret_cast<>

Поверил, так тоже не выйдет. Простейший указатель на метод в gcc занимает 8 байт. Там должен быть адрес и еще что-то. Адрес ты резолвишь, а вот про оставшиеся 4 байта надо курить маны :)


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 29, 2007, 16:52
Цитата: "Alex Forth"
попробуй преобразовывать тип с помощью reinterpret_cast<>

Поверил, так тоже не выйдет. Простейший указатель на метод в gcc занимает 8 байт. Там должен быть адрес и еще что-то. Адрес ты резолвишь, а вот про оставшиеся 4 байта надо курить маны :)

Не понял. Подробнее.

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

 Слушай, у меня есть подозрение, что я гений!
Зачем мучаться с класами? По одиночке я же спокойно каждую функцию могу ресолвить? Только первым параметром надо добалять void* a_la_this. Размер класса я знаю, что мне мешает написать:
Код:

typedef void (*TMapAccess_constr_type)(void* map);
typedef int (*TMapAccess_OpenMap_type)(void* map, const char * mapname, int mode);
...
class TMyMapAccess: public QObject
{
Q_OBJECT
public:
TMyMapAccess(QObject * parent = 0);
...
private:
QLibrary lib;
void *map;// TMapAccess *map;
}

TMyMapAccess::TMyMapAccess(QObject * parent)
: QObject(parent)
{
lib.setFileName("mapacces");
lib.load();
map = malloc(129040 /*sizeof(TMapAccess)*/ );
TMapAccess_constr_type map_constr = (TMapAccess_constr_type)lib.resolve(TMapAccess_constr_type_str);
if (!map_constr) {
QMessageBox::critical(0,"TMyMapAccess error!","Can't load TMapAccess constructor!");
return;
}
map_constr(map);
}

int TMyMapAccess::OpenMap(const char * mapname, int mode)
{
TMapAccess_OpenMap_type map_OpenMap = (TMapAccess_OpenMap_type)lib.resolve(TMapAccess_OpenMap_type_str);
if (!map_OpenMap) {
QMessageBox::critical(0,"TMyMapAccess error!","Can't load TMapAccess constructor!");
}
return map_OpenMap(map,mapname,mode);
}


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

 Получается, что я просто пишу простенькую оболочку для класса, используя только те функции, что мне нужны... :)
Если поднапрячься, то вполне можно парсер написать, который мне по всем функциям пройдется и напишет шаблонный код! :)
Только сначала надо будет руками по def-файлу пройтись. :(

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

 ЗЫ. Самое прикольное, что просто передача дополнительного первого аргумента РАБОТАЕТ!!! Проверил пока 4 функции: конструктор, деструктор, OpenMap и CloseMap.

добавлено спустя 31 минуту:

 PPS. Отрисовка из dll на HDC работает на УРА! :) Все! Я счастлив! Жизнь налаживается. Теперь будем делать это все красиво. Парсер буду писать(эх, ща буду Perl вспоминать)!
Alex Forth, с меня ПИВО! :) Будешь в Москве - пиши в личку, втретимся - проставлюсь. Гут?

Тему, думаю, можно закрывать.

добавлено спустя 25 минут:

 PPPS. навсякий случай, чтобы сия ценная инфа не потерялась, запостил решение еще сюда:
http://www.rsdn.ru/Forum/message/1586925.flat.aspx


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 29, 2007, 20:01
Минут десять втыкал в приведенный выше код. Так до конца и не понял, почему он должен работать! Если ничего не глючит, то, скорее всего, тебе просто повезло. Дело в том, что (код привожу не совсем точный, главное общий смысл)
Код:

typedef void (*method_ptr)(void*, int);
method_ptr  myPtr = resolve("MyClasssomeMethod");
MyClass *instancePtr;
myPtr(instancePtr,1);//Внимание, ключевое место

и
Код:

MyClass instance;
instance.someMethod(1);//Внимание, ключевое место

соответствуют разному коду. В первом случае instancePtr - это обычный аргумент и он будет ложится в стек последним, перед вызовом функции. Во втором варианте, укахатель на экземпляр класса передается неявно ч-з регистр. Поидее в WIN, для совместимости с MSVC он должен перeдаваться ч-з ECX.

Также не забывай про то, что
1)виртуальные функции вызываются вообще по своему. (Их резолвить ненадо, но от этого не легче).
2) Если есть иерархия классов, то при вызове каждого метода компилятор расчитывает значение THIS исходя из особенностей конкретной иерархии.
3)Наверняка есть особенности, про которые я не вспомнил.

ИМХО Вывод: путем резолва заюзать класс из DLL можно. НО! Лично я, на практике пошел бы другим путем. Чего и тебе советую.

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

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


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 29, 2007, 20:34
Цитата: "Alex Forth"

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

То есть ты мне предлагаешь вернуться к тому, с чего начали??? Я не хочу писать то, что уже написано. Да и зачем тогда это делать в библиотеке? Если уж напишу, то буду юзать сразу по месту требования.
Цитата: "Alex Forth"

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

Че-то совсем стремно. Даже я со своим вариантом не настолько манов укурился. :) Да и потом, как начальству объяснить, благодаря бубнам какой марки ЭТО работает?


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 29, 2007, 20:43
Цитировать

То есть ты мне предлагаешь вернуться к тому, с чего начали??? Я не хочу писать то, что уже написано. Да и зачем тогда это делать в библиотеке? Если уж напишу, то буду юзать сразу по месту требования.

Ты все понял неверно!
Сейчас у тебя есть враппер?  Вот я и предлагаю его:
1) перенести в свою dll
2) Офигенно упростить

ЗЫ: Щас поужинаю и набросаю примерчик такого подхода.

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

Обещанный пример:
Пусть в чужой библиотеке (A.dll) есть такой класс
Код:

class A
{
...
public:
      A(char*);
     ~A();
      int  foo1(int);
      int  foo2(int);
      int  foo3(int);
}


Делаем свою wrapA.dll c таким классом:
Код:

class WrapA
{
     A*     impl;
public:
      WrapA(char* a)
     {
         impl = new A(a);
     }

      ~WrapA()
      {
         delete impl;
      };

      virtual int  foo1(int a)
      {
          return impl->foo1(a);
      };

      virtual int  foo2(int a)
      {
          return impl->foo2(a);
      };

      virtual int  foo3(int a)
      {
          return impl->foo3(a);
      };
}

//функция спец-враппер для конструктора
WrapA* createWrapA(char* a)
{
  return new WrapA( a );
}


Твоя программа будет иметь дело только с wrapA.dll (Будет ее динамически подгружать и дергать все необходимые методы).


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 31, 2007, 13:29
Цитата: "Alex Forth"

Ты все понял неверно!
Сейчас у тебя есть враппер?

Нет. Есть только несколько "свраппеных" функций чисто для теста, как оно работает. Всего в dll порядка 10-15 классов(от 40 до 150 функций в каждом), около 500-700 просто функций. Короче, в pexports мне пишет 3500 с чем-то экспортируемых строк.
Цитата: "Alex Forth"

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

А как еще? У меня на руках только dll. Lib от нее я сделать так и не смог. В принципе с этого и начиналась эта тема: "как правильно сделать либу?".
Цитата: "Alex Forth"

Обещанный пример:
...
Твоя программа будет иметь дело только с wrapA.dll (Будет ее динамически подгружать и дергать все необходимые методы).

Вопрос: а если у меня все равно будет враппер, то зачем мне его в dll пихать? Или dll у dll сама все выдергивает и мне не надо писать враппер?
По-моему, выхода здесь два:
1) сделать нормальную либу, чтобы не делать враппер
2) сделать враппер, а потом на основе него объект qobject и наследовать далее... И без dll.


Название: Ааа провтыкал :(
Отправлено: Alex Forth от Июль 31, 2007, 15:11
Цитировать
А как еще? У меня на руках только dll. Lib от нее я сделать так и не смог. В принципе с этого и начиналась эта тема: "как правильно сделать либу?".

Как-то я вначале тебя не понял :( ,  думал тебе надо обязательно в динамике грузить.
При таком раскладе надо копать создание библиотеки импорта. По другому тяжелее.
ЗЫ: почитай еще за формат def файла  и посмотри в сторону утилитки c++filt


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Июль 31, 2007, 16:04
так. перечитай внимательно всю эту тему. Там уже написано, что я пробовал делать с def-ом. Может чего подскажешь?
утилитку поищу...


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Июль 31, 2007, 16:35
Цитировать
Там уже написано, что я пробовал делать с def-ом. Может чего подскажешь?

Имена функций наверное по разному заманглены, вот и не работает.
Попробуй сначала сделать тестовую dll с помощью gcc и распотрошить ее c pexport и dlltool.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 05, 2007, 21:48
Цитата: "Alex Forth"
Цитировать
Там уже написано, что я пробовал делать с def-ом. Может чего подскажешь?

Имена функций наверное по разному заманглены, вот и не работает.
Попробуй сначала сделать тестовую dll с помощью gcc и распотрошить ее c pexport и dlltool.

Не понял. А причем тут dll на gcc? У меня есть конкретная dll, походу на Delphi. Какое имя он хочет увидеть, линкер пишет. Прочитай подробнее предыдущие посты. Написано тут: http://prog.org.ru/forum/ptopic_26588.html#26588


Название: [4.3.0-win] Как быть с dll?
Отправлено: Racheengel от Август 05, 2007, 22:35
http://www.softsoft.ru/development/components-libraries/12322.htm

Цитировать

DLL to Lib – это магическая сервисная программа, которая преобразует DLL файл в его эквивалент статичного файла библиотеки. После этого, вы можете переместить настоящий DLL файл с статичным файлом библиотеки, перестроить это приложение и распространять с DLL файлом! Самая важная особенность это то, что процесс обработки не требует каких-либо источников кодов DLL файлов! Все работы происходят из двоичного в двоичный. DLL to Lib интегрируется со многими утилитами, включая "Import Library Reference Information Generator", "Symbol Finder" и т.д. для того, чтобы вы были уверены, что процесс конверсии успешен.



Оно?


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Август 06, 2007, 09:31
Цитата: "Icoz"

Не понял. А причем тут dll на gcc? У меня есть конкретная dll, походу на Delphi. Какое имя он хочет увидеть, линкер пишет.

dll на gcc - это чтобы потренироваться :)
Ты в первом посте писал:
Цитата: "Icoz"

Причем с -p (прописывание алиасов с префиксами) перепробовал по разному! Так хотя бы компилируется (после подправления ручками def-файла), но при запуске пишет, что функция такая-то не найдена по пути "..." и прочее...

Отсюда я делаю вывод, что pexport и dlltool dll успешно разобрали, но в библиотеке импорта они сгенерировали некоректные для твоей dll имена. Следовательно, копай в эту сторону.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 06, 2007, 11:13
Цитата: "Alex Forth"

Отсюда я делаю вывод, что pexport и dlltool dll успешно разобрали, но в библиотеке импорта они сгенерировали некоректные для твоей dll имена. Следовательно, копай в эту сторону.

Вывод правильный. Как только имена "правильные" и оно компилится, то тут же и не запускается! А пишет, что не найдено!!!
Так что у меня только 2 варианта получилось:
1) не компилится, ибо имя "неправильное"
2) компилится, но не находит функцию, ибо для gcc имя "правильное", а вот винда его в библиотеке не находит! :(


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Август 06, 2007, 16:30
Ищи третий вариант, когда и компилится и запускается :)


Название: [4.3.0-win] Как быть с dll?
Отправлено: Racheengel от Август 07, 2007, 00:08
Пробовали утилитку таки?


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 09, 2007, 12:15
нет еще. Никак руки не дойдут.


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 11, 2007, 22:16
попробовал. Программка конвертит DLL в LIB для статической линковки, а при этом требует некие IMPLIB, откуда он собственно хочет взять то, что я раньше здесь называл "lib для неявного подключения dll к exe".
Кароче, прога делает статическую либу, которую можно будет подцепить так, чтобы dll вообще не была нужна - она внутри exe.
Тогда вопрос, откуда тогда взять IMPLIB?
Точнее мне достаточно просто IMPLIB
PS. Чтобы дальше не было недоразумений по поводу терминологии: IMPLIB - import library, LIB - static library, DLL - dynamic library

ИТАК, мне надо IMPLIB!

добавлено спустя 3 часа:

 Делаю вот так:
Код:
pexports -h include\mapacces.h my.dll > my.def
dlltool -Dmapacces.dll -dmapacces.def -llibmapacces.a -k

Прога компилится, но не запускается, пишет, что не могу найти "mapOpenMap@8". В самой dll лежит просто "mapOpenMap", но gcc ищет при линковке именно "mapOpenMap@8".
Как быть? Как заставить gcc линковать правильно?

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

 Мдя
http://www.geocities.com/yongweiwu/stdcall.htm


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 12, 2007, 20:47
скрипт на перле для автоматического создания хидера и cpp для враппера уже готов наполовину! :)
IMPLIB я так и не смог сделать... gcc упорно ищет func@N вместо func!
А про классы я вообще молчу! Там он такие кракозябры запрашивает!!!


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Август 13, 2007, 08:23
Для эксперимента была взята первая попавшаяся dll из c:/windows/system32 ею оказалась ALut.dll.
Далее:
Код:

pexports ALut.dll > alut.def

alut.def правлю вручную до состояния:
Код:

LIBRARY ALUT.dll
EXPORTS
alutExit@0 =  alutExit @3
alutInit@0 = alutInit @3
.... и т д согласно правилам именования stdcall ( правда я не понял, почему не нужен символ  "_"? :( )

потом
Код:

dlltool -DALut.dll -dalut.def -llibalut.a

в срр файле пишу так:
Код:

extarn "C" __stdcall void alutInit();

int main(int argc, char** argv)
{
alutInit();
}

Все работает :)


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 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 напишу... :)


Название: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Август 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, библиотеки импорта и внутри твоих обьектніх файлов. Как только во всех перечисленніх местах имена будут одни и теже, все заработает :)


Название: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 14, 2007, 21:02
как только имена одни и те же, то у меня все собирается, но не запускается. см выше

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

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

В результате он все равно ищет при запуске mapCloseMap@4


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Август 23, 2007, 14:24
поднимаю вопрос наверх. Проблема так и не решена.
Пока делаю временную хрень типа враппера. Почти готово, только дикий гемор, ибо там между классами стремные связи.
КАК СДЕЛАТЬ IMPORT LIB ДЛЯ gcc?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Сентябрь 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).




Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Разуев Максим от Сентябрь 05, 2007, 08:06
Кстати из dll можно получить класс. Для этого в нормальных dll-ках должна быть функция get_interface. Тогда имея виртуальный класс описанный в хидере и получив интерфейс можно работать с dll.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: vaprele07 от Сентябрь 05, 2007, 09:58
Alex Forth
как у тебя осуществляется связь с thisObject (Дескриптор объекта) ::) ведь все остальные, кроме конструктора, функции должны знать!. где лежит ихний родитель?

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

Есть такая штука DeDe, помнится она красиво и наглядно импортировала дэльфевые классы.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Сентябрь 05, 2007, 11:26
Цитировать
Alex Forth
как у тебя осуществляется связь с thisObject (Дескриптор объекта)  ведь все остальные, кроме конструктора, функции должны знать!. где лежит ихний родитель?
Давай попорядку. Есть класс, а есть екземпляр класса. Каждый не static метод класса должен получать указатель на экземпляр класса, с которым он должен работать. Ты это имел ввиду?

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

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

ЗЫ: Только что понял - я забыл протестировать импорт виртуальных методов. Там должны быть свои сюрпризы  ;D


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 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).
то есть заменить? Небольшой кусок кода дай, как оно должно выглядеть в заменненом варианте...


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 05, 2007, 22:17
Есть такая штука DeDe, помнится она красиво и наглядно импортировала дэльфевые классы.
Что-то я такую прогу в нете не нашел. Название поточнее не помните?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: vaprele07 от Сентябрь 06, 2007, 06:05
http://reversing.kulichki.ru/files/dizas/DeDe.rar


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Alex Forth от Сентябрь 06, 2007, 09:55
Цитировать
то есть заменить? Небольшой кусок кода дай, как оно должно выглядеть в заменненом варианте...

Все просто :)
Вместо __attribute__ ((dllimport)) пиши DECL_IMPORT


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 06, 2007, 15:06
Повторюсь, но сие очень важно:

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

У кого есть идеи как по симпатичнее достать все эти замангленные имена? Писать скрипт, который по аргументам соберет нужное имя - отпадает, ибо задачка не слишком тривиальная... :(


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 07, 2007, 15:10
DeDe мою библиотеку не кушает. Она не делфевая, а просто борландовская. Скорее всего borland c++ 5.02 (старый, еще до билдера)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: vaprele07 от Сентябрь 07, 2007, 15:47
так скачай новую версию либы, я там посмотрел у них даже qt проскакивает, за общайся с авторами... может они тебе помогут?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 09, 2007, 17:28
так скачай новую версию либы, я там посмотрел у них даже qt проскакивает, за общайся с авторами... может они тебе помогут?
Не понял:
1) Скачать новую версию DeDe? Или моей либы, которую пытаюсь распотрошить?
2) Авторы опять же DeDe или моей либы? Если авторами моей либы - то нет, пробовали уже. Дохлый номер, народ пытается нам тупо втюхать другой свой продукт. Нам же надо работать с ЭТОЙ dll. Так что обновить версию ее невозможно.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 16, 2007, 21:19
поднимаю наверх, проблема не решена.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Tonal от Сентябрь 17, 2007, 05:39
Создай новую тему, опиши в краце что хочешь сделать и что не получается.
А то искать среди 5и страниц что же тебе надо как-то в лом. ;-)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 17, 2007, 13:45
Вкратце не выйдет! Тем более мне опять напишут те самые 5 страниц, что можно сделать!
Так ты хоть ознакомишься с тем, что предложили, проверили и отвергли.

А суть проблемы: надо в винде подключить dll к проге. Есть dll, есть хидеры, к ней НЕТ lib (import library).
QLibrary отпадает, ибо там куча классов. Всего порядка 3500 экспортируемых функций.
Подробнее читай предыдущие посты


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 23, 2007, 16:25
еще раз поднимаю.
Проблема все еще имеется в наличии


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Tonal от Сентябрь 23, 2007, 18:23
Если компилишь mingw и либа слинкована им же, или имеет только С экспорты - можно просто указать её в списке либ.
Если нет - то всё сильно зависит от...


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 24, 2007, 19:57
Почитай посты в самом начале (штуки 3-4) и 3-5 с конца, чтобы достаточно вникнуть в проблему.
Dll сделана в borland'е, скорее всего Borland C++ 5.02. ImpLib к ней нету.
Надо ее подрубить к проге.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Tonal от Сентябрь 24, 2007, 20:35
Если используется экспорт классов, то напрямую подрубить - дохлый номер.
Проще сделать так:
1) Найти компилятор, которым это чудо собрано.
2) Собрать им dll-переходник которая импортирует твою, а экспортирует чистый С-ишный апи.
3) Подцепить переходник из мингвы.

В принципе, вместо/вместе с чистым С, если согласовать выравнивания, можно обмениваться интерфейсами. Я так делал.

Можно ещё COM прикрутить, но это уже для мазахистов, т.к. ни для багланда ни для мингвы нормальных лёгких библиотек нету... ;)

P.S. насчёт DeDe - бред. ;)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 25, 2007, 19:24
Если используется экспорт классов, то напрямую подрубить - дохлый номер.
Читай выше, кое-что подрубается. Через QLibrary я смог поштучно подрубать все функции класса, явно передавая в них (обычно неявный) указатель this. Слишком тяжело, ибо там 10-15 классов крупных (по 100-150 функций) и с десяток помельче (10-30 функций). Руками анрил, после скрипта все равно много работы.

Проще сделать так:
1) Найти компилятор, которым это чудо собрано.
2) Собрать им dll-переходник которая импортирует твою, а экспортирует чистый С-ишный апи.
3) Подцепить переходник из мингвы.
Допустим проблему с 1 и 3 я решу. А про п.2 по-подробнее рассказать можешь? Пример кода что ли?...
Скажем для класса(только с условием, что там по 100-150 функций... как-то по рациональней что ли...):
Код:
class Test{
public:
int func1(int,double);
void func2(int) inline; // или как там? короче с инлайн функциями
};


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Tonal от Сентябрь 26, 2007, 06:57
Если используется экспорт классов, то напрямую подрубить - дохлый номер.
Читай выше, кое-что подрубается. Через QLibrary я смог поштучно подрубать все функции класса, явно передавая в них (обычно неявный) указатель this. Слишком тяжело, ибо там 10-15 классов крупных (по 100-150 функций) и с десяток помельче (10-30 функций). Руками анрил, после скрипта все равно много работы.
А кто сказал, что функции из дллки выдернуть незя?
А вот глюков при этом  отловить - запросто. Самые очевидные:
1) Если есть исключения - будет глючить.
2) Если память выделяется в разных модулях - будет глючить (например память выделилась в обычной функции а удалилась в инлайне)
3) Если попытаешся отнаследоваться - будет глючить.
4) Если будешь использовать dynamic_cast - будет глючить.
5) Если в параметрах/возвратах используются не только POD типы - будет глючить.
Это только на вскидку...

Теоретически, всё это можно разрулить...
Практически - я бы взялся, за "многа денгаф" и без каких-либо гарантий. ;-)

2) Собрать им dll-переходник которая импортирует твою, а экспортирует чистый С-ишный апи.
Допустим проблему с 1 и 3 я решу. А про п.2 по-подробнее рассказать можешь? Пример кода что ли?...
Скажем для класса(только с условием, что там по 100-150 функций... как-то по рациональней что ли...):
Код:
class Test{
public:
int func1(int,double);
void func2(int) inline; // или как там? короче с инлайн функциями
};
Довольно просто.
Заголовок будет выглядеть так:
Код:
extern "C" {
typedef void* HTest;
HTest test_create();
void test_destroy(HTest);
int test_func1(HTest, int, double);
void test_func2(HTest, int);
}
Реализация - тривиально.

Если объем классов очень уж большой, то можно нарисовать скриптик (python, perl, ets) который по исходному заголовочнику быстро соорудит заготовку. Дальше допиливаешь неоднозначности, разруливаешь перегрузки, и собираешь.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 26, 2007, 21:47
Если объем классов очень уж большой, то можно нарисовать скриптик (python, perl, ets) который по исходному заголовочнику быстро соорудит заготовку. Дальше допиливаешь неоднозначности, разруливаешь перегрузки, и собираешь.
Хидеры у меня родные есть, только не помогают.
Пока так и делаю, только скрипт написать так, чтобы он прямо по хидеру работал, для меня тяжко (там парсер нехилый нужен). Поэтому я сначала руками специально готовлю хидер (что тоже тяжко, ибо хидеры почти полметра весят! их там файлов 40-45), чтобы его кушал мой скрипт.
Так что, к сожалению, ты мне ничего нового (кроме как обширный список глюков) не сказал.

Вопрос-то изначально стоял иначе: как подрубить dll без излишних телодвижений? Хидеры есть (это самое главное, ибо по ним известен размер классов), а вот все эти шаманства с переходниками... много бубнов программерских попереломаю. :(

Есть ли способ получить implib для этой dll?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Tonal от Сентябрь 27, 2007, 06:27
Яж таби и объясняю, что подрубить можно, но работать оно не будет.
Никакой implib не спасёт, т.к. глюки лезут от несовместимости внутренних механизмов разных компиляторов.

Единственное, что можно сделать, это нарисовать б/м "умный" набор скриптов.

P.S. Ещё можно подождать до выхода следующего стандарта С++, или лучше послеследующего. Там вопросам совместимости некоторое внимание начали уделять. ;-)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Сентябрь 27, 2007, 12:43
Смешно. :( Меня начальство уже сейчас трясет...  :-\


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Октябрь 16, 2007, 23:16
UP :)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: T800 от Октябрь 17, 2007, 00:11
Единственный реальный способ когда все будет работать -
1. Создать в том же компиляторе на котором написана библиотека либ-файл по принципу - заколовок  плюс .cpp в котором все методы есть но они пустые.
2. Создать СOM+ библиотеку врапперов всего чего там есть НА ТОМ ЖЕ КОМПИЛЯТОРЕ
3. А вот с помощью ее MIDL-ов пользоваться этими COM-бъектами уже из под той среды, что тебе нужна.
Очень много работы и без скриптов  не обойдешся (займет  при том объеме который заявлен порядка квартала в одиночу плюс съеденный бессонницей мозг)
Большой минус такой реализации - потеря быстродейсвия


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Вячеслав от Октябрь 17, 2007, 11:03
А аффтору денег за либу не проще заслать (если она так нужна ?) Просто любой секс со сторонним либами (закрытыми) может кончиться abort'ом ;) Как уже было сказанно - можно руками сделать все _но_ 1) нужно собирать проект тем-же компилятором , с теми-же настройками 2) Никто не гарантирует что это будет работать надежно ... IMHO для любого коммерческого проекта( даже не всмысле получения денег,а в смысле эксплуатации и минимизации головной(и не только ;) ) боли) использование таких библиотек должго быть _очень сильно_ мотивировано ...


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: pastor от Октябрь 17, 2007, 14:30
А аффтору денег за либу не проще заслать (если она так нужна ?) Просто любой секс со сторонним либами (закрытыми) может кончиться abort'ом ;) Как уже было сказанно - можно руками сделать все _но_ 1) нужно собирать проект тем-же компилятором , с теми-же настройками 2) Никто не гарантирует что это будет работать надежно ... IMHO для любого коммерческого проекта( даже не всмысле получения денег,а в смысле эксплуатации и минимизации головной(и не только ;) ) боли) использование таких библиотек должго быть _очень сильно_ мотивировано ...

+1

Полностью согласен

ЗЫ: А что за либа такая? Может есть её аналоги?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Октябрь 18, 2007, 14:25
... IMHO для любого коммерческого проекта ... использование таких библиотек должго быть _очень сильно_ мотивировано ...

Проект не коммерческий, а военный.

ЗЫ: А что за либа такая? Может есть её аналоги?

Либа как либа. Аналоги есть, и их куча. Но по ТЗ мы имеем право использовать только ее, ибо она сертифицирована, прошла госприемку и прочее...


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: pastor от Октябрь 18, 2007, 16:59
Проект не коммерческий, а военный.

Если ваше предприятие занимаеться столь серьёзными проектами, разве оно не может купить лицензию на эту либу? Весьма странно... К томуже, такого рода хаки значительно понизают надёжность систему (имхо для вас это немаловажно)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Вячеслав от Октябрь 18, 2007, 17:13
Проект не коммерческий, а военный.
Эта , а приемку как вы собираетесь проходить ? Тут у нас коллег зарубили на подобном финте :(
Проще все-таки импорт нарыть (хоть и за деньги)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Октябрь 18, 2007, 20:39
Проект не коммерческий, а военный.

Если ваше предприятие занимаеться столь серьёзными проектами, разве оно не может купить лицензию на эту либу? Весьма странно... К томуже, такого рода хаки значительно понизают надёжность систему (имхо для вас это немаловажно)
Лицензия есть. Есть dll, есть хидер. Всё. Это все, что нужно разработчику. Остальное - его проблемы. Тем более та контора пытается заставить перейти на другой их продукт, ессно, и за другие деньги...
Эта , а приемку как вы собираетесь проходить ? Тут у нас коллег зарубили на подобном финте :(
Проще все-таки импорт нарыть (хоть и за деньги)
Знал бы ты, как эти конторки работают - ночами бы не спал, зная, чем тебя "охраняют". :(


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Вячеслав от Октябрь 18, 2007, 22:30
Проект не коммерческий, а военный.

Если ваше предприятие занимаеться столь серьёзными проектами, разве оно не может купить лицензию на эту либу? Весьма странно... К томуже, такого рода хаки значительно понизают надёжность систему (имхо для вас это немаловажно)
Лицензия есть. Есть dll, есть хидер. Всё. Это все, что нужно разработчику. Остальное - его проблемы. Тем более та контора пытается заставить перейти на другой их продукт, ессно, и за другие деньги...
Эта , а приемку как вы собираетесь проходить ? Тут у нас коллег зарубили на подобном финте :(
Проще все-таки импорт нарыть (хоть и за деньги)
Знал бы ты, как эти конторки работают - ночами бы не спал, зная, чем тебя "охраняют". :(
Не поверишь - сам от-туда (из вояк) ;) Про длл и проблемы разрабочика - контора в корне не права - нехай дают пример как их длл использовать - их можно прижать по требованиям ГОСТ'а - тебе-ж самому(или) нет придеться рисовать доку на программу _по_ ГОСТУ :( А про конторки - знаю , но сплю ;) Любимая жена под боком - очень этому способствует ;)
 


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: T800 от Октябрь 19, 2007, 08:34
Если нет договора, в котором указано, что подобная дока (по ГОСТу) должна быть, то хрен ты ее получишь. ЗЫ.Тоже работаю в таком месте.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Вячеслав от Октябрь 19, 2007, 09:13
Если нет договора, в котором указано, что подобная дока (по ГОСТу) должна быть, то хрен ты ее получишь. ЗЫ.Тоже работаю в таком месте.
Эта , а если не секрет _где_ это возможно для оборонки не делать документацию по госту для изделий с литерой О1 ?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Октябрь 19, 2007, 15:43
Так, народ! Вас куда-то не туда понесло!
У нас тема обсуждения другая!
Надо подключить либу, а не выяснять, где sqrt(зла)!


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: serkul от Октябрь 20, 2007, 00:02
Судя по дате создания топика автор давно бы смог вручную набрать враппер ;))).
Я сталкивался с похожими проблемами, и все, что мне удалось найти гласит - классы из ДЛЛ могут быть нормально использованы только тем компилятором, на котором писались.

Цитировать
Надо подключить либу, а не выяснять, где sqrt(зла)!
Вернемся к первой странице ;) - пиши враппер ). имхо создаётся впечатление, что тебя интересует не подгрузка фунций, а сам процесс.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Октябрь 20, 2007, 10:39
Судя по дате создания топика автор давно бы смог вручную набрать враппер ;))).
Я сталкивался с похожими проблемами, и все, что мне удалось найти гласит - классы из ДЛЛ могут быть нормально использованы только тем компилятором, на котором писались.

Цитировать
Надо подключить либу, а не выяснять, где sqrt(зла)!
Вернемся к первой странице ;) - пиши враппер ). имхо создаётся впечатление, что тебя интересует не подгрузка фунций, а сам процесс.
Я пишу, но вручную 3500 функций - сам развлекайся. Так что у меня скрипт на Перле + напильник. Но все равно пока хреновато получается... Полтора метра хидеров переработать в одиночку за месяц (особенно, если учесть, что я еще в инсте на дневном учусь да и вторая работа имеется) нереально. Самое обидное, что вреппер не потестишь, пока целиком его не напишешь для ВСЕХ классов, ибо между ними очень плотная взаимосвязь! :(


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: T800 от Октябрь 29, 2007, 05:51
Хотелось бы знать что это за библиотека страшная.... не меньше QЕ по объему.... или SDK панорамы? У нас похожую задачку с панорамой пытались втюхать потом пришли к решению что это неработоспособно и перешли на новый продукт. Затраты  потенциальные несоизмеримы с эффектом плюс вобщемто это частичто нарушало авторские права - библитека импорта создавалась под один компилятор и подразумевалось, что будет работать с ним. Разработка враппера , модифицирующего функциональность продукта без согласования с авторами - нарушение лицензии к сожалению.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Tonal от Октябрь 29, 2007, 07:22
Насчёт авторских прав, по моему ты не прав. ;-)
Врапер - твоя собственная разработка. Продукт ты не модифицируешь, а просто используешь. К тому-же именно в нужном компиляторе.
Так что если нет специальных пунктов в лицензии (кстати, как они могут выглядеть?) то всё вполне легально.
Причём, даже если бы Icoz начал пачить либу, по нашем законом это было бы вполне нормально. :-)


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Октябрь 30, 2007, 22:54
2 Tonal
Ну про патчить - это уже вопрос спорный. При желании можно подмять и под нарушение авторских прав, и под "несанкционирование вмешательство в работу ЭВМ и сетей" (так вроде в УК написано). Нет, в длл я не лезу. Оно мне нафиг не нужно...
2 Т800
Про панораму ты почти прав. Что-то вроде этого


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Май 05, 2008, 22:30
нашел на rsdn следующую вещь: http://www.rsdn.ru/Forum/?mid=98720
Цитировать
У борланда указанный прототип функции приведет к внутреннему имени функции MyProc
У майкрософта указанный прототип функции приведет к внутреннему имени функции _MyProc@0

Линкеры обоих будут разыскивать в lib-файлах (библиотеках импорта) именно внутренние имена. При успешной компиляции и линковке каждый нашел свое. Весь вопрос в библиотеках импорта — какой способ связывания в них прописан. Скорее всего — по имени. Раз так, то клиент, собранный борландом, будет искать в dll имя MyProc — и, о чудо!, найдет его. Клиент, собранный VC, будет искать MyProc@0 — и, горе ему!, не найдет такого.

Итак, дело в библиотеках импорта. Если бы они оба использовали либы, связывающие по ординалам, оба с достоинством выполнили бы задачу.
Собссно вопрос: как указать линкеру, чтобы он юзал связывание по ординалам, а не по имени?


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Tonal от Май 06, 2008, 07:15
Используй *.def файлы.


Название: Re: [4.3.0-win] Как быть с dll?
Отправлено: Icoz от Май 06, 2008, 13:50
Так. А подробнее?
По-моему в этой теме я писал уже по def-ам много всего.
В частности, см. посты http://prog.org.ru/forum/index.php/topic,6032.msg26588.html#msg26588 (http://prog.org.ru/forum/index.php/topic,6032.msg26588.html#msg26588) и http://prog.org.ru/forum/index.php/topic,6032.msg26539.html#msg26539 (http://prog.org.ru/forum/index.php/topic,6032.msg26539.html#msg26539). Как видишь, def я и юзаю.