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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: dll и разные компиляторы  (Прочитано 11315 раз)
QCasper
Гость
« : Октябрь 24, 2007, 10:55 »

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

Попробуй поиграться Calling convention options: __stdcall должен быть.
Записан
Вячеслав
Гость
« Ответ #2 : Октябрь 24, 2007, 12:28 »

В общем случае с использованием классов - IMHO никак - забодаешься с разными косяками бороться .... особенно весело получаеться, когда используються разные менеджеры памяти Грустный (new из одной rtl а delete из другой).....
Записан
QCasper
Гость
« Ответ #3 : Октябрь 24, 2007, 12:32 »

Попробуй поиграться Calling convention options: __stdcall должен быть.

Можно подробнее, что именно нужно сделать?
Записан
Tonal
Гость
« Ответ #4 : Октябрь 24, 2007, 13:16 »

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

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

Про хорошее:
Можно передавать интерфейсы - пустые структуры содержащие только чисто виртуальные функции. ;-)
Записан
QCasper
Гость
« Ответ #5 : Октябрь 24, 2007, 13:56 »

Смысл такой: имеется интерфейс, и имеется класс, который от него унаследован. Функции, которые экспортируются выглядят так:

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

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

Где не так? Что доделать?
Записан
Daemon
Гость
« Ответ #6 : Октябрь 24, 2007, 14:09 »

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

Name mangling? Использовать для экспортируемых функций cdecl и extern "C".

extern "C" используется, посмотрите внимательнее на код, где прописать cdecl?
Записан
Вячеслав
Гость
« Ответ #8 : Октябрь 24, 2007, 15:12 »

Народ , не забудте о простой вещи - если и длл и прога используют ту-же Qt - получиться ахинея - они будут ссылаться на _разные_ библиотеки с одним названием ....
Записан
Литий
Гость
« Ответ #9 : Октябрь 24, 2007, 15:34 »

Код:
extern "C" {
__declspec(dllexport)  IVideoGrabber* newInstance() {
return new VideoGrabber;
}
__declspec(dllexport)  void destroyInstance(IVideoGrabber *vgb) {
delete vgb;
}
}
Записан
Daemon
Гость
« Ответ #10 : Октябрь 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.
« Последнее редактирование: Октябрь 24, 2007, 16:04 от Daemon » Записан
Alex03
Гость
« Ответ #11 : Октябрь 26, 2007, 08:20 »

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

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

Ага, а после того как для сборки DLL начинаю использовать MSVC, то пути сразу становятся нормальными и Qt выпрямляется? Улыбающийся
Записан
QCasper
Гость
« Ответ #13 : Октябрь 26, 2007, 09:53 »

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

не помогло... кстати IVideoGrabber - наследник QObject, может быть это пагубно влияет? Улыбающийся
Записан
Вячеслав
Гость
« Ответ #14 : Октябрь 26, 2007, 10:07 »

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

ЗЫ А на куя такие танцы с бубнами ? не проще собрать две dll из одного кода , но с разными именами ?
« Последнее редактирование: Октябрь 26, 2007, 10:12 от Вячеслав » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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