C++更改 Thrift 文件后出现链接器错误

发布于 2024-09-11 04:41:14 字数 6133 浏览 3 评论 0原文

我认为这与 C++ 链接器错误有关,而不是与 thrift 有关。我对 thrift 文件进行了更改并重新生成了 cpp & java 类。进行此更改后,我开始在 cpp 中收到链接器错误。这是错误

未定义的符号:

"com::XXXX::thrift::employee::SavingsInfo::operator<(com::XXXX::thrift::employee::SavingsInfo const&) const",引用自: std::less::operator()(com::XXXX::thrift::employee::SavingsInfo const&, com::XXXX::thrift::employee::SavingsInfo const&) constin employee_types.o
ld:未找到符号
Collect2: ld 返回 1 退出状态
make: *** [ThriftCPPSamples] 错误 1

我将 SavingsInfo 类型添加到 thrift 文件中,这是我所做的更改。我将文档中提到的所有选项提供给 g++。我给了 -I/usr/local/include/thrift, -I/boost 路径-L/boost-lib 路径-lthrift。但更改后我开始收到上述链接器错误。我不明白这是为什么。该错误指向由节俭产生的东西。错误的原因可能是什么?

这个错误与“operator <”有关,所以我只发布与其相关的代码。完整的代码可以从最后提供的两个链接中获得。

employee_types.h

class SavingsInfo {
public:
    std::string name;
    double amount;
    bool operator == (const SavingsInfo & rhs) const { /*...*/ }
    bool operator != (const SavingsInfo &rhs) const { return !(*this == rhs); }
    bool operator < (const SavingsInfo & ) const;
    uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};

class EmployeeInfo {
public:
    int32_t id;
    std::string name;
    double salary;
    bool contract;
    std::set<std::string>  dependents;
    std::set<SavingsInfo>  savings;
    bool operator == (const EmployeeInfo & rhs) const { /*...*/ }
    bool operator != (const EmployeeInfo &rhs) const { return !(*this == rhs); }
    bool operator < (const EmployeeInfo & ) const;
    uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};

employee_types.cpp

uint32_t EmployeeInfo::read(::apache::thrift::protocol::TProtocol* iprot) {
    uint32_t xfer = 0;
    std::string fname;
    ::apache::thrift::protocol::TType ftype;
    int16_t fid;
    xfer += iprot->readStructBegin(fname);
    using ::apache::thrift::protocol::TProtocolException;
    while (true)
    {
        xfer += iprot->readFieldBegin(fname, ftype, fid);
        if (ftype == ::apache::thrift::protocol::T_STOP) {
            break;
        }
        switch (fid)
        {
            // removed the case statements which deal with reading other fields
        case 6:
            if (ftype == ::apache::thrift::protocol::T_SET) {
                {
                    this->savings.clear();
                    uint32_t _size6;
                    ::apache::thrift::protocol::TType _etype9;
                    iprot->readSetBegin(_etype9, _size6);
                    uint32_t _i10;
                    for (_i10 = 0; _i10 < _size6; ++_i10)
                    {
                        SavingsInfo _elem11;
                        xfer += _elem11.read(iprot);
                        this->savings.insert(_elem11);
                    }
                    iprot->readSetEnd();
                }
                this->__isset.savings = true;
            } else {
                xfer += iprot->skip(ftype);
            }
            break;
        default:
            xfer += iprot->skip(ftype);
            break;
        }
        xfer += iprot->readFieldEnd();
    }
    xfer += iprot->readStructEnd();
    return xfer;
}

uint32_t EmployeeInfo::write(::apache::thrift::protocol::TProtocol* oprot) const {
    uint32_t xfer = 0;
    // removed the write statements for other fields
    xfer += oprot->writeStructBegin("EmployeeInfo");
    xfer += oprot->writeFieldBegin("savings", ::apache::thrift::protocol::T_SET, 6);
    {
        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRUCT,   
            this->savings.size());
        std::set<SavingsInfo> ::const_iterator _iter13;
        for (_iter13 = this->savings.begin(); _iter13 != this->savings.end(); ++_iter13)
        {
            xfer += (*_iter13).write(oprot);
        }
        xfer += oprot->writeSetEnd();
    }
    xfer += oprot->writeFieldEnd();
    xfer += oprot->writeFieldStop();
    xfer += oprot->writeStructEnd();
    return xfer;
}

我尝试过的其他一些事情:

  1. 如果我使用 SavingsInfo,而不是 set,它​​可以正常工作。
  2. 评论“运算符<”在employee_types.h中,因为我无法弄清楚它在哪里使用。我收到以下构建错误

构建文件:../src/employee_types.cpp 调用:GCC C++ 编译器 g++ -I/usr/local/include/thrift -I/Users/raghava/Software/Boost_C++_Library/boost_1_43_0 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/employee_types .d" -MT"src/employee_types.d" -o"src/employee_types.o" "../src/employee_types.cpp" /usr/include/c++/4.2.1/bits/stl_function.h:在成员函数 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = com: :xxxx::节俭::员工::储蓄信息]': /usr/include/c++/4.2.1/bits/stl_tree.h:982:从 'std::pair::iterator, bool> 实例化std::_Rb_tree<_Key、_Val、_KeyOfValue、_Compare、_Alloc>::_M_insert_unique(const _Val&) [其中 _Key = com::xxxx::thrift::employee::SavingsInfo、_Val = com::xxxx::thrift ::employee::SavingsInfo、_KeyOfValue = std::_Identity、_Compare = std::less、_Alloc = std::allocator]' /usr/include/c++/4.2.1/bits/stl_set.h:307:从 'std::pair, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> 实例化std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = com::xxxx::thrift::employee::SavingsInfo, _Compare = std::less, _Alloc = std::allocator ]' ../src/employee_types.cpp:163:从这里实例化 /usr/include/c++/4.2.1/bits/stl_function.h:227:错误:与“operator<”不匹配在 '__x <; __y' make: *** [src/employee_types.o] 错误 1

这两个文件的完整源代码在下面的链接中给出。另一个链接在评论中(在我获得 10 点声誉之前我无法发布它)。

employee_types.cpp -- http://pastebin.com/7dLtstCK
employee_types.h -- http://pastebin.com/JGzE8V6J

谢谢。

问候, 拉加瓦。

I think this is related to C++ linker error than to thrift. I made a change to the thrift file and regenerated cpp & java classes. After this change, I started getting linker errors in cpp. Here is the error

Undefined symbols:

"com::XXXX::thrift::employee::SavingsInfo::operator<(com::XXXX::thrift::employee::SavingsInfo const&) const", referenced from:
std::less::operator()(com::XXXX::thrift::employee::SavingsInfo const&, com::XXXX::thrift::employee::SavingsInfo const&) constin employee_types.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [ThriftCPPSamples] Error 1

I added SavingsInfo type to thrift file, this is the change that I made. I give all the options mentioned in the doc to g++. I gave -I/usr/local/include/thrift,
-I/path-to-boost, -L/path-to-boost-lib, -lthrift. But after the change I started getting the above linker error. I couldn't understand the reason for this. The error points to something that was generated by thrift. What could be the reason for the error?

This error is about "operator <", so I am posting only the code relevant to it. Full code is available from the two links provided at the end.

employee_types.h

class SavingsInfo {
public:
    std::string name;
    double amount;
    bool operator == (const SavingsInfo & rhs) const { /*...*/ }
    bool operator != (const SavingsInfo &rhs) const { return !(*this == rhs); }
    bool operator < (const SavingsInfo & ) const;
    uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};

class EmployeeInfo {
public:
    int32_t id;
    std::string name;
    double salary;
    bool contract;
    std::set<std::string>  dependents;
    std::set<SavingsInfo>  savings;
    bool operator == (const EmployeeInfo & rhs) const { /*...*/ }
    bool operator != (const EmployeeInfo &rhs) const { return !(*this == rhs); }
    bool operator < (const EmployeeInfo & ) const;
    uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};

employee_types.cpp

uint32_t EmployeeInfo::read(::apache::thrift::protocol::TProtocol* iprot) {
    uint32_t xfer = 0;
    std::string fname;
    ::apache::thrift::protocol::TType ftype;
    int16_t fid;
    xfer += iprot->readStructBegin(fname);
    using ::apache::thrift::protocol::TProtocolException;
    while (true)
    {
        xfer += iprot->readFieldBegin(fname, ftype, fid);
        if (ftype == ::apache::thrift::protocol::T_STOP) {
            break;
        }
        switch (fid)
        {
            // removed the case statements which deal with reading other fields
        case 6:
            if (ftype == ::apache::thrift::protocol::T_SET) {
                {
                    this->savings.clear();
                    uint32_t _size6;
                    ::apache::thrift::protocol::TType _etype9;
                    iprot->readSetBegin(_etype9, _size6);
                    uint32_t _i10;
                    for (_i10 = 0; _i10 < _size6; ++_i10)
                    {
                        SavingsInfo _elem11;
                        xfer += _elem11.read(iprot);
                        this->savings.insert(_elem11);
                    }
                    iprot->readSetEnd();
                }
                this->__isset.savings = true;
            } else {
                xfer += iprot->skip(ftype);
            }
            break;
        default:
            xfer += iprot->skip(ftype);
            break;
        }
        xfer += iprot->readFieldEnd();
    }
    xfer += iprot->readStructEnd();
    return xfer;
}

uint32_t EmployeeInfo::write(::apache::thrift::protocol::TProtocol* oprot) const {
    uint32_t xfer = 0;
    // removed the write statements for other fields
    xfer += oprot->writeStructBegin("EmployeeInfo");
    xfer += oprot->writeFieldBegin("savings", ::apache::thrift::protocol::T_SET, 6);
    {
        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRUCT,   
            this->savings.size());
        std::set<SavingsInfo> ::const_iterator _iter13;
        for (_iter13 = this->savings.begin(); _iter13 != this->savings.end(); ++_iter13)
        {
            xfer += (*_iter13).write(oprot);
        }
        xfer += oprot->writeSetEnd();
    }
    xfer += oprot->writeFieldEnd();
    xfer += oprot->writeFieldStop();
    xfer += oprot->writeStructEnd();
    return xfer;
}

Couple of other things that I have tried:

  1. Instead of set<SavingsInfo>, if I use SavingsInfo, it works fine.
  2. Commented "operator <" in employee_types.h since I couldn't figure out where this was getting used. I got the following build error


Building file: ../src/employee_types.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include/thrift -I/Users/raghava/Software/Boost_C++_Library/boost_1_43_0 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/employee_types.d" -MT"src/employee_types.d" -o"src/employee_types.o" "../src/employee_types.cpp"
/usr/include/c++/4.2.1/bits/stl_function.h: In member function 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = com::xxxx::thrift::employee::SavingsInfo]':
/usr/include/c++/4.2.1/bits/stl_tree.h:982: instantiated from 'std::pair::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = com::xxxx::thrift::employee::SavingsInfo, _Val = com::xxxx::thrift::employee::SavingsInfo, _KeyOfValue = std::_Identity, _Compare = std::less, _Alloc = std::allocator]'
/usr/include/c++/4.2.1/bits/stl_set.h:307: instantiated from 'std::pair, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = com::xxxx::thrift::employee::SavingsInfo, _Compare = std::less, _Alloc = std::allocator]'
../src/employee_types.cpp:163: instantiated from here
/usr/include/c++/4.2.1/bits/stl_function.h:227: error: no match for 'operator<' in '__x < __y'
make: *** [src/employee_types.o] Error 1

Complete source code of these 2 files is given in below links. The other link is in the comments (I cannot post it until I get 10 pts of reputation).

employee_types.cpp -- http://pastebin.com/7dLtstCK
employee_types.h -- http://pastebin.com/JGzE8V6J

Thank you.

Regards,
Raghava.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文