Russian Qt Forum

Qt => Общие вопросы => Тема начата: QCasper от Октябрь 24, 2007, 10:55



Название: dll и разные компиляторы
Отправлено: QCasper от Октябрь 24, 2007, 10:55
Написал приложение, и dll'ку. Приложение собрал с помощью g++, dll - с помощью msvc. В результате, приложение не хочет грузить dll'ку (QLibrary::load()). Если для сборки приложения тоже использовать msvc, то все нормально - dll'ка грузится. Вопрос: как написать, с использованием Qt, dll'ку, которую можно будет загружать любым приложением, в независимости от того, чем собрано оно и сама dll'ка?


Название: Re: dll и разные компиляторы
Отправлено: WW от Октябрь 24, 2007, 11:03
Попробуй поиграться Calling convention options: __stdcall должен быть.


Название: Re: dll и разные компиляторы
Отправлено: Вячеслав от Октябрь 24, 2007, 12:28
В общем случае с использованием классов - IMHO никак - забодаешься с разными косяками бороться .... особенно весело получаеться, когда используються разные менеджеры памяти :( (new из одной rtl а delete из другой).....


Название: Re: dll и разные компиляторы
Отправлено: QCasper от Октябрь 24, 2007, 12:32
Попробуй поиграться Calling convention options: __stdcall должен быть.

Можно подробнее, что именно нужно сделать?


Название: Re: dll и разные компиляторы
Отправлено: Tonal от Октябрь 24, 2007, 13:16
Ограничения:
Нужно чтобы dll-ка экспортировала только pure C функции.
Все функции должны быть объявлены как extern "C"
Параметры и возвраты должны быть или простые типы, или указатели (возможно ссылки) на структуры (по значению структуры передавать/возвращать нельзя)
Для каждой функции нужно явно указать соглашение о вызове (calling convention) например __stdcall или __ccall
Если передаёшь/возвращаешь указатели/ссылки на структуры, то нужно убедиться, что совпадает выравнивание.
Исключения не должны вылетать за пределы dll-ки, и колбеки, которые использует dll-ка не должны их генерить.

Память, выделенная в dll должна освобождаться там же.
dll Не должна пытаться освободить переданную ей память.
(Исключение составляет память выделенная функциями WinApi)

Про хорошее:
Можно передавать интерфейсы - пустые структуры содержащие только чисто виртуальные функции. ;-)


Название: Re: dll и разные компиляторы
Отправлено: QCasper от Октябрь 24, 2007, 13:56
Смысл такой: имеется интерфейс, и имеется класс, который от него унаследован. Функции, которые экспортируются выглядят так:

Код:
extern "C" {
IVideoGrabber* newInstance() {
return new VideoGrabber;
}
void destroyInstance(IVideoGrabber *vgb) {
delete vgb;
}
}

где VideoGrabber наследован от IVideoGrabber.

Где не так? Что доделать?


Название: Re: dll и разные компиляторы
Отправлено: Daemon от Октябрь 24, 2007, 14:09
Name mangling? Использовать для экспортируемых функций cdecl и extern "C".


Название: Re: dll и разные компиляторы
Отправлено: QCasper от Октябрь 24, 2007, 14:39
Name mangling? Использовать для экспортируемых функций cdecl и extern "C".

extern "C" используется, посмотрите внимательнее на код, где прописать cdecl?


Название: Re: dll и разные компиляторы
Отправлено: Вячеслав от Октябрь 24, 2007, 15:12
Народ , не забудте о простой вещи - если и длл и прога используют ту-же Qt - получиться ахинея - они будут ссылаться на _разные_ библиотеки с одним названием ....


Название: Re: dll и разные компиляторы
Отправлено: Литий от Октябрь 24, 2007, 15:34
Код:
extern "C" {
__declspec(dllexport)  IVideoGrabber* newInstance() {
return new VideoGrabber;
}
__declspec(dllexport)  void destroyInstance(IVideoGrabber *vgb) {
delete vgb;
}
}


Название: Re: dll и разные компиляторы
Отправлено: Daemon от Октябрь 24, 2007, 15:59
Name mangling? Использовать для экспортируемых функций cdecl и extern "C".

extern "C" используется, посмотрите внимательнее на код, где прописать cdecl?
Там же, где и происходит экспорт.
extern "C" нужно не для definition, а для declaration. К примеру:
Код:
\\ где-нибудь в С++ файле:
IVideoGrabber* newInstance() {
return new VideoGrabber;
}
void destroyInstance(IVideoGrabber *vgb) {
delete vgb;
}

\\где-нибудь в месте экспорта:
extern "C" __declspec(dllexport) IVideoGrabber* __cdecl newInstance();
extern "C" __declspec(dllexport) void __cdecl destroyInstance(IVideoGrabber *vgb);
Причем учти, что могут быть проблемы, если один из параметров функции или возвращаемое значения - указатель на шаблонный класс, и т.д., в этом случае даже эти штучки с calling convention не помогут, компайлер заманглит имена до не узнаваемости. Лучше уж просто использовать указатели на  void.


Название: Re: dll и разные компиляторы
Отправлено: Alex03 от Октябрь 26, 2007, 08:20
ИМХО если у QCasper-а не грузится сама либа в QLibrary::load(), то соглашения о вызове и т.д. тут не при чём. Т.е. до resolv дело ещё не дошло.
Дело или в самой DLL, тогда я б посоветовал создать пустую DLL c DllMain визардом MSVC и попытаться загрузить её.
Ну или дело в путях, в Qt и т.д.! :)


Название: Re: dll и разные компиляторы
Отправлено: QCasper от Октябрь 26, 2007, 09:47
ИМХО если у QCasper-а не грузится сама либа в QLibrary::load(), то соглашения о вызове и т.д. тут не при чём. Т.е. до resolv дело ещё не дошло.
Дело или в самой DLL, тогда я б посоветовал создать пустую DLL c DllMain визардом MSVC и попытаться загрузить её.
Ну или дело в путях, в Qt и т.д.! :)

Ага, а после того как для сборки DLL начинаю использовать MSVC, то пути сразу становятся нормальными и Qt выпрямляется? :)


Название: Re: dll и разные компиляторы
Отправлено: QCasper от Октябрь 26, 2007, 09:53
Код:
extern "C" {
__declspec(dllexport)  IVideoGrabber* newInstance() {
return new VideoGrabber;
}
__declspec(dllexport)  void destroyInstance(IVideoGrabber *vgb) {
delete vgb;
}
}

не помогло... кстати IVideoGrabber - наследник QObject, может быть это пагубно влияет? :)


Название: Re: dll и разные компиляторы
Отправлено: Вячеслав от Октябрь 26, 2007, 10:07
МЯФ !!!!! У тебя форточки пытаються работать с двумя разными копиями qtcore Как с одной :) И как ты себе это представляешь ? Твоя прога грузит свой вариант qt собраный mingw , а dll требует qt собраный msvc и чего получиться ? + про рантайм vs не забудь (если ms 2005 - то еще .net framework) ....

ЗЫ А на куя такие танцы с бубнами ? не проще собрать две dll из одного кода , но с разными именами ?


Название: Re: dll и разные компиляторы
Отправлено: QCasper от Октябрь 26, 2007, 11:01
МЯФ !!!!! У тебя форточки пытаються работать с двумя разными копиями qtcore Как с одной :) И как ты себе это представляешь ? Твоя прога грузит свой вариант qt собраный mingw , а dll требует qt собраный msvc и чего получиться ? + про рантайм vs не забудь (если ms 2005 - то еще .net framework) ....

ЗЫ А на куя такие танцы с бубнами ? не проще собрать две dll из одного кода , но с разными именами ?

Дело в том, что dll нельзя собрать с помощью g++, там код представляет собой помесь Qt и DirectShow, a g++ такие вещи не умеет.


Название: Re: dll и разные компиляторы
Отправлено: Вячеслав от Октябрь 26, 2007, 11:15
Ну тады флаг в руки ;) IMHO - занятие бесполезное так-как ABI у gcc и vs все-таки разный :(
Хотя - если удасться добиться устойчивой работы такого - ставлю ящик пыва ;)


Название: Re: dll и разные компиляторы
Отправлено: Tonal от Октябрь 26, 2007, 14:54
А чего именно не умеет g++ в DirectShow? ATL?


Название: Re: dll и разные компиляторы
Отправлено: QCasper от Октябрь 26, 2007, 15:32
А чего именно не умеет g++ в DirectShow? ATL?

Я с этим вопросом особо не разбирался, но факт тот, что не умеет.
Вот, что ответили в рассылке: http://lists.trolltech.com/qt-interest/2007-08/thread00984-0.html
Вот местное обсуждение: http://prog.org.ru/forum/index.php/topic,6169.0.html Кстати здесь Ваша же цитата:
Цитировать
Platform SDK от MS не совместим с mingw.


Название: Re: dll и разные компиляторы
Отправлено: Tonal от Октябрь 26, 2007, 18:17
Попробуй заменить пакет w32 на последний - w32api-3.10.tar.gz
И попробуй собрать dll-ку мингвой, убрав все ссылки на PSDK.
Если DirectShow не последний, может и соберётся...

Если нет - тогда остаётся попытайся разделить вынести всё Qt из dll-ки, оставив только DirectShow, ну и экспортировать из неё только чистые С функции и интерфейсы...


Название: Re: dll и разные компиляторы
Отправлено: Gryz от Ноябрь 01, 2007, 14:49
не помогло... кстати IVideoGrabber - наследник QObject, может быть это пагубно влияет? :)

мне почему то кажется, что это плохо :) Интерфейс не должен иметь членов, кроме vtable