GCC + operator::double() -> неизвестный символ (ARM Linux)
От: Tujh Голландия  
Дата: 19.10.09 08:13
Оценка:
Здравствуйте.
Столкнулся с непонятным для меня поведением компилятора GCC 4.1.1 (arm-linux-g++ если быть точным)
Описание достаточно общирное, так как вопрос мне не понятен, постараюсь объяснить подробно.
Проект — динамическая библиотека (.dll/.so) под M$Win(x86) и Linux (ARM) по опросу некоторого типа устройств. Согласно протокола обмена числа с плавающей точкой хранятся в устройстве в виде пары целых чисел, соответственно захотелось удобств и приделал оператор приведения к double. Выглядело это первоначально так:

// dev_functions.hpp
    typedef boost::uint32_t         ulong;
...
    typedef struct
            {
                ulong p_int;
                ulong p_dec;
                operator double();
            }                       index;
...
    std::string crc16(const void *ptr, const size_t length);

// dev_functions.cpp
    //
    index::operator double()
    {
        double l_int = static_cast<double> (p_int);
        double l_dec = static_cast<double> (p_dec);
        l_dec /= 100000000.0;
        return (l_int + l_dec);
    }
    //-------------------------------------------------------------------------
    // 
    std::string crc16(const void *ptr, const size_t length)
    {
        [skip]
    }
    //-------------------------------------------------------------------------

// currents.cpp

            ...
            l_str.assign(response, 22, 8);
            index l_vol;
            memcpy(&l_vol, l_str.c_str(), sizeof(index));
            m_de_map[de_low_address::dev::current::volume]->set_value(
                static_cast<double> (l_vol),
                quality_good,
                l_ptime,
                false
                );
            ...

ни чего особо хитрого, структура, с перегруженным оператором приведения заполняется простым копированием участка памяти.
Под MSVC2005 (VC8.0) все прекрасно собралось в .dll и так же отлично работало.
При сборке с arm-linux-g++ ни каких особых проблем не было, но вот при работе программы, использующей эту .so возникли проблемы, точнее сообщение '...unknown symbol indexcvd...' с последующим "падением" приложения. Место локализовалось быстро, нет реализации оператора приведения в double.
Путем "бубнения" был найден следующий код, который работает в GCC
// dev_functions.hpp
    typedef boost::uint32_t         ulong;
...
    typedef struct
            {
                ulong p_int;
                ulong p_dec;
                operator double()
                {
                    double l_int = static_cast<double> (p_int);
                    double l_dec = static_cast<double> (p_dec);
                    l_dec /= 100000000.0;
                    return (l_int + l_dec);
                }
            }                       index;
...
    std::string crc16(const void *ptr, const size_t length);

// dev_functions.cpp
    // 
    std::string crc16(const void *ptr, const size_t length)
    {
        [skip]
    }
    //-------------------------------------------------------------------------

// currents.cpp

            ...
            l_str.assign(response, 22, 8);
            index l_vol;
            memcpy(&l_vol, l_str.c_str(), sizeof(index));
            m_de_map[de_low_address::dev::current::volume]->set_value(
                static_cast<double> (l_vol),
                quality_good,
                l_ptime,
                false
                );
            ...

в таком варианте все работает. Хотя по сути, изменений — только перенос кода из .срр в .hpp
Вариант с тем, что в makefile не был включен нужный .о или .срр файл исключен, так как функция crc16 (приведена в листинге) из этого файла прекрасно работала, а значит компилировалась и линковалась.

Может кто сталкивался с таким поведением gcc или просто знает ответ, просветите пожалуйста, почему реализация, прописанная в .cpp игнорировалась.

Заранее благодарю.
Re: GCC + operator::double() -> неизвестный символ (ARM Linu
От: andrey.desman  
Дата: 19.10.09 10:18
Оценка: 2 (1)
Здравствуйте, Tujh, Вы писали:

// dev_functions.hpp
    typedef boost::uint32_t         ulong;
...
    // Надо дать структуре имя, а не через имя typedef оперделять оператор
    typedef struct index
            {
                ulong p_int;
                ulong p_dec;
                operator double();
            }                       index;
...
    std::string crc16(const void *ptr, const size_t length);
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.