Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > dynamic_cast между dll-ками


Автор: borisbn 1.2.2011, 17:19
Добрый день всем.
Читая документацию по Qt набрёл на такую фразу в описании ф-ции qobject_cast
Цитата

The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries.

из чего я делаю вывод, что dynamic_cast может не работать across dynamic library boundaries.
Погуглив на тему rtti, dynamic_cast, shared libraries и т.п., нашёл несколько обсуждений на эту тему, но
1) все они касались передачи между библиотеками указателей на шаблонные классы
2) везде присутствовало упоминание о gcc

Провёл такой эксперимент на MSVC 2008
сделал два проекта DLL и консольный.
код DLL-ки

i_face.h
Код

#if defined( RTTI_TEST_EXPORTS )
    #define FUNCTION_DECLSPEC dllexport
#else
    #define FUNCTION_DECLSPEC dllimport
#endif

template< typename T >
class IFace {
public:
    virtual ~IFace(){}
    virtual void foo() = 0;
};

typedef IFace< int > IFaceInt;

//---------------
#include <stdio.h>

template< typename T >
class FaceImpl : public IFace< T > {
public:
    ~FaceImpl(){}
    virtual void foo() {
        T x = 0;
        printf( "FaceImpl::foo %d\n", x );
    }
    void fooImpl() {
        T x = 3;
        printf( "FaceImpl::fooImpl %d\n", x );
    }
};

__declspec( FUNCTION_DECLSPEC ) IFaceInt * creafeFace();


i_face.cpp
Код

#include "i_face.h"

IFaceInt * creafeFace() {
    return new FaceImpl< int >();
}


и код консольной программы
Код

#include "../rtti_test/i_face.h"
#pragma comment( lib, "../Debug/rtti_test.lib" )

int main() {
    IFace< int > * face = creafeFace();
    face->foo();
    FaceImpl< int > * faceImpl = dynamic_cast< FaceImpl< int > * >( face );
    faceImpl->fooImpl();
    FaceImpl< float > * faceImpl_f = dynamic_cast< FaceImpl< float > * >( face );
    printf( "%p\n", faceImpl_f );
    delete face;
    return 0;
}


выводит, как и ожидалось, так
Цитата

FaceImpl::foo 0
FaceImpl::fooImpl 3
00000000

т.е. всё в порядке.

теперь собственно
вопрос:
1) Что это за проблема "RTTI across dynamic library boundaries" ?
2) Кто-нибудь сталкивался с проблемой передачи указателя на базовый класс между библиотеками с последующим dynamic_cast'ом его ?
3) Просьба проверить это на gcc, т.к. на liveworkspace или на codepad создать и загрузить потом *.so нельзя.

Спасибо


P.S. То, что dynamic_cast "вырастает" из-за плохого проектирования - знаю и стараюсь никогда не использовать. Так что вопрос скорее из теоретической области, нежели из практической

Автор: bsa 1.2.2011, 18:15
3.gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5):
Цитата
FaceImpl::foo 0
FaceImpl::fooImpl 3
(nil)


Может проблема имеется только в случае плагинов (загрузки библиотек в рантайме) или при использовании dynamic_cast в библиотеке?..

Автор: borisbn 1.2.2011, 19:53
bsa, спасибо. А ты также делал *.so + *.executable ?
Завтра попробую загружать через QLibrary::resolve и вариант с cast'ом в dll-ке.

Автор: bsa 1.2.2011, 20:13
Цитата(borisbn @  1.2.2011,  20:53 Найти цитируемый пост)
А ты также делал *.so + *.executable ?

да.

Мне вообще не понятно, какая может быть проблема. Ведь информация о типе хранится в vtable.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)