Название: Динамическая библиотека, использующая Qt Отправлено: Вудруф от Март 14, 2006, 14:13 Написал функции с использованием Qt, оформил в виде динамической библиотеки. Написал программу, загружающую эту dll во время работы. Откомпилировал gcc - работает.
Загружаю ту же dll из Builder'а с использованием тех же функций. OpenLibrary и т.д. - не работает! Делаю ещё одну отладочную версию библиотеки с выводом доп. информации в процессе работы. Убеждаюсь, что все параметры были переданы правильно, QHttp инициализирован, присоединился и скачал данные. Однако readAllData возвращает ахинею. Собственно, вопрос: Как такое возможно? Это же уже откомпилированный код... Название: Динамическая библиотека, использующая Qt Отправлено: Dendy от Март 14, 2006, 14:47 А программа, загружающая DLL написана тоже на Qt? Работает, скомпиллировав из GCC, но не работает, скомпиллировав из Builder?
Название: Динамическая библиотека, использующая Qt Отправлено: Вудруф от Март 15, 2006, 08:23 Нет, это просто код, не привязанный к Qt. Загружая библиотеку из Билдера, получаю в работе чушь (но функция вызывается с правильными параметрами!!!), загружая библиотеку из gcc, всё работает как надо.
Код:
Название: Динамическая библиотека, использующая Qt Отправлено: Dendy от Март 15, 2006, 13:59 Могу только посоветовать вставить побольше отладочной информации в DLL. На каком именно месте она начинает работать по разному.
Название: Динамическая библиотека, использующая Qt Отправлено: Вудруф от Март 15, 2006, 15:02 На этом:
return http -> readAll().data(); где http - экземпляр QHttp Название: Динамическая библиотека, использующая Qt Отправлено: Dendy от Март 15, 2006, 15:45 Ха! Ну так всё понятно, дружище. Ошибка в DLL - тьІ юзаешь освободившуюся память. В зависимости от параметров сборки на етапе вьІполнения ето может позволиться, а может и нет.
Вопрос, что делает такая строка: Код: return http->readlAll().data(); 1. СчитьІвает данньІе и заносит их в екземпляр QByteArray. 2. Сохраняет указатель на реальньІе данньІе в QByteArray. 3. Уничтожает QByteArray, вьІходя из метода readAll(), и, так как ссьІлка на данньІе бьІла одна, - сами данньІе. 4. Возвращает указатель на только что удалённьІе данньІе. Вообще небезопастньІй метод - возвращать указатель на данньІе неизвестного размера. Ещё небезопастно пользоваться разньІми версиями CRT библиотеки: DLL память вьІделяет, а программа уничтожает. СамьІй правильньІй способ - пользоваться С-интерфейсом со структурами, например: Код: struct http_data_t :D Название: Динамическая библиотека, использующая Qt Отправлено: Hordi от Март 15, 2006, 16:16 To Dendy:
немножко неверно...(но в целом выводы правильные) data() вернет указатель на неудаленные данные, но после выхода из return данные будут уничтожены. Это работает: const char* get(const char *p) { //данные, на которые указывает p валидны return p; } const char *p = get( std::string("11111111").c_str() ); //а тут уже данные невалидны std::cerr << p << '\n'; Название: Динамическая библиотека, использующая Qt Отправлено: Dendy от Март 15, 2006, 18:07 To Hordi
Немного не соглашусь: Код: const char * data = http->readAll().constData(); Название: Динамическая библиотека, использующая Qt Отправлено: Hordi от Март 15, 2006, 18:20 так я так же и написал - это то же самое, что и мой второй пример
Название: Динамическая библиотека, использующая Qt Отправлено: Dendy от Март 15, 2006, 18:51 Да, я вижу. Но первьІй пример непонятен.
Цитата: "Hordi" data() вернет указатель на неудаленные данные, но после выхода из return данные будут уничтожены. Я вот с етим не соглашался. ДанньІе будут уничтоженьІ в таком порядке: Код: const char * data = QString( "ABC" ).toLatin1().toLower().constData(); 1. Конструктор QString( "ABC" ) 2. Метод toLatin1() инкрементирует ссьІлку на QByteArray( "ABC" ) (до 2) и тут же декрементирует (до 1) 3. Метод toLower() инкрементирует ссьІлку на QByteArray( "abc" ) (до 2) и тут же декрементирует (до 1) 4. Метод constData() просто возвражает указатель 5. ВьІзьІвается деструктор QByteArray( "abc" ) и уничтожает свои данньІе 6. ВьІзьІвается дектруктор QByteArray( "ABC" ) и уничтожает свои данньІе 7. ВьІзьІвается деструктор QString( "ABC" ) и уничтожает свои данньІе 8. ВьІзьІвается следующая операция после вьІражения. Все данньІе уже уничтоженьІ Название: Динамическая библиотека, использующая Qt Отправлено: Hordi от Март 15, 2006, 19:03 Будут, но только если return не передается непосредственно в функцию (уничножен при передаче в функцию будет после завершения функции).
Т.е. нижеприведенный код работает правильно (в середине функции func все OK): void func( const char *p ) { ...работа с p } int main() { func( QString( "ABC" ).toLatin1().toLower().constData() ); } Название: Динамическая библиотека, использующая Qt Отправлено: Dendy от Март 15, 2006, 20:27 Согласен. Но стрёмно как-то (-:
Название: Динамическая библиотека, использующая Qt Отправлено: Hordi от Март 15, 2006, 20:57 Почему стремно? Это абсолютно нормально.
Название: Динамическая библиотека, использующая Qt Отправлено: Steven_Orko от Март 15, 2006, 22:48 Цитата: "Dendy" Согласен. Но стрёмно как-то (-: Я даже скажу больше... Так тоже нормально: Код: QString mefunc() Но соглашусь с этим: Код: const char * data = QString( "ABC" ).toLatin1().toLower().constData(); QString( "ABC" ) - временный объект, который будет существавоть до конца вычисления значения всего выражения... т.е., как правильно уже сказали, data уже использовать после этой строки нельзя... Название: Динамическая библиотека, использующая Qt Отправлено: Вудруф от Март 16, 2006, 06:53 Ошибка понятна, всем спасибо!!!
|