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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Один код работет в Builder, но не работает в Qt  (Прочитано 5509 раз)
nvrrus
Гость
« : Апрель 04, 2011, 10:58 »

Здравствуйте, уважаемые форумчане! Помогите, пожалуйста разобраться с одной пробш

Проблема использования билдеровской библиотеки в Qt

В обоих случаях работаю с функциями библиотеки собранной в Builder.
Получаю интерфейс I_archSource.
Вызываю последовательно три метода, GetListOfQueries, size, Get. Каждый при отработке выводит сообщение с названием метода.

Builder:

Код:
            I_archSource *m_Src;

            const GUID xxx = {0xa167cb35, 0x2572, 0x453d, 0x876a, 0x1b4a24f7f40e};

            //CreateInstance - функция библиотеки собранной в Builder (получаем объект с интерфейсом I_archSource для работы с библиотекой)
            CreateInstance(xxx, (void**)&m_Src);
           
            I_QuerriesList* Queries;

            m_Src->GetListOfQueries((void*)getPstk(),  (void*)&getConnect(), sizeof(CONNECTKLIENT), &Queries);

            unsigned size = Queries->size();

            I_archQuery* Q = Queries->Get(0);

Все четко отрабатывает. В итоге три сообщения - GetListOfQueries, size, Get

Qt:
Код:
    I_archSource *m_Src;

    GUID xxx = {0xa167cb35, 0x2572, 0x453d, 0x876a, 0x1b4a24f7f40e};

    //Acreate_instance - функция той же библиотеки выгруженная из нее динамически (получаем объект с интерфейсом I_archSource //для работы с библиотекой)
    Acreate_instance(xxx, (void**)&m_Src);

    I_QuerriesList* Queries;

    m_Src->GetListOfQueries(NULL, NULL, 0, &Queries);

    unsigned size = Queries->size();

    I_archQuery* Q = Queries->Get(0);

Валится на последней строчке  I_archQuery* Q = Queries->Get(0);

При этом если пройти size() и встать на последнюю строчку получаю два сообщения: GetListOfQueries, Get (вместо GetListOfQueries, size)

Заранее спасибо! Буду очень признателен, если что-то подскажете.
Записан
nvrrus
Гость
« Ответ #1 : Апрель 04, 2011, 12:54 »

Нашли ошибку. Кажется она в Билдере.

Это интерфейс нашей библиотеки собранной в билдере:

Код:
class I_QuerriesList : public C_UnknownStub
{
public:
    virtual void clear() = 0;
    virtual void push_back(I_archQuery* Q) = 0;
    virtual unsigned size() = 0;
    virtual I_archQuery* Get(unsigned i) = 0;
};

class C_UnknownStub : public IUnknown
{
private:
    volatile long m_cRef;
public:
    C_UnknownStub();
    virtual~C_UnknownStub();

    virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject);
    virtual ULONG __stdcall AddRef();
    virtual ULONG __stdcall Release();
};

Билдер не заносит виртуальный деструктор в таблицу виртуальных функций. А Qt заносит (что правильно).
Поэтому происходит сдвиг при вызове. Вместо  clear() вызывается push_back, вместо push_back, size(). И т.д.

Убрали виртуальный деструктор, все заработало...

Но так же нельзя, без виртуального деструктора... Подскажите, пожалуйста, может кто сталкивался с этой проблемой.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #2 : Апрель 04, 2011, 18:18 »

>>А Qt заносит
Qt - библиотека классов, она ничего не заносит. Этим занимается компилятор.

Можно попробовать поискать нужные ключи к борландовскому компиллеру, или порытся по поводу этого нюанса в тырнете, вдруг патч какой-нибудь есть.

Или рискнуть собрать вашу библиотеку не борландовским компиллером
Записан

Юра.
Tonal
Гость
« Ответ #3 : Ноябрь 08, 2011, 18:52 »

Скорее всего ошибка в функции GetListOfQueries.
Либо в общих хедерах.
У багланда в реализации COM-овских классов применяется "уличная магия" - отрицательные смещения для спец. методов типа деструктора. В связи с этим могут наблюдаться разные глюки при портировании.

Советы по переносимости:
В общих хедерах могут быть только константы, фукции, структуры и интерфейсы (полностью абстрактные классы).
У общих интерфейсов не должно быть деструкторов.
Всем функциям и методам следует явно задать соглашения о вызове (calling conversion).
Передавать или возвращать структуры по значению не рекомендуется.
Передавать или возвращать float-ы и/или double нежелательно.
Выравнивание данных должно совпадать.
Освобождать память и другие ресурсы следует там же где выделяли.

Эти советы не являются абсолютными, их можно нарушать, но при этом следует хорошо понимать что происходит в каждом конкретном случае на уровне ассемблера в обоих компиляторах. Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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