You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Thrift TThreadedServer编译错误:vtable for MessageProcessorFactory未定义引用

构建Thrift TThreadedServer时undefined reference to vtable for MessageProcessorFactory错误排查

问题描述

构建Thrift TThreadedServer服务器时出现链接错误,编译日志提示undefined reference to vtable for MessageProcessorFactory,移除MessageProcessorFactory指针后错误消失。相关信息如下:

编译日志

[main] Building folder: Thrift_client_server 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build "/home/konstantin/c++ projects/Thrift_client_server/build" --config Debug --target all -j 14 --
[build] Consolidate compiler generated dependencies of target server
[build] [ 50%] Building CXX object CMakeFiles/server.dir/server.cpp.o
[build] [100%] Linking CXX executable server
[build] /usr/bin/ld: CMakeFiles/server.dir/server.cpp.o: warning: relocation against `_ZTV23MessageProcessorFactory' in read-only section `.text._ZN23MessageProcessorFactoryC2ERKSt10shared_ptrI16MessageIfFactoryE[_ZN23MessageProcessorFactoryC5ERKSt10shared_ptrI16MessageIfFactoryE]'
[build] /usr/bin/ld: CMakeFiles/server.dir/server.cpp.o: in function `MessageProcessorFactory::MessageProcessorFactory(std::shared_ptr<MessageIfFactory> const&)':
[build] /home/konstantin/c++ projects/Thrift_client_server/api/gen-cpp/Message.h:209: undefined reference to `vtable for MessageProcessorFactory'
[build] /usr/bin/ld: warning: creating DT_TEXTREL in a PIE
[build] collect2: error: ld returned 1 exit status
[build] gmake[2]: *** [CMakeFiles/server.dir/build.make:98: server] Error 1
[build] gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/server.dir/all] Error 2
[build] gmake: *** [Makefile:91: all] Error 2
[proc] The command: /usr/bin/cmake --build "/home/konstantin/c++ projects/Thrift_client_server/build" --config Debug --target all -j 14 -- exited with code: 2
[driver] Build completed: 00:00:01.631
[build] Build finished with exit code 2

原始CMakeLists.txt

cmake_minimum_required(VERSION 3.11)
project(server)

set(THRIFT_LIB_DIR "/home/konstantin/thrift/thrift-0.19.0")

find_library(THRIFT_LIB thrift ${THRIFT_LIB_DIR})

add_executable(${PROJECT_NAME} server.cpp)

target_link_libraries(${PROJECT_NAME} ${THRIFT_LIB})

服务器代码

#include <thrift/server/TThreadedServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TTransport.h>
#include <thrift/TProcessor.h>
#include <thrift/transport/TBufferTransports.h>
#include <memory>
#include <string>

#include "api/gen-cpp/Message.h"

using namespace ::apache::thrift::server;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift;

class MessageHandler : public MessageIf
{
public:
    virtual void mes(std::string &_return) override
    {
        _return = "Hello from the server";
    }
    virtual ~MessageHandler(){}
};

class MessageHandlerFactory : public MessageIfFactory
{
public:
    virtual MessageIf *getHandler(const ::apache::thrift::TConnectionInfo &connInfo)
    {
        return new MessageHandler();
    }

    virtual void releaseHandler(MessageIf *handler)
    {
        delete handler;
    }

    virtual ~MessageHandlerFactory(){}
};

int main(){
    
    std::shared_ptr<MessageIfFactory> handler_factory = std::make_shared<MessageHandlerFactory>();
    auto processor_factory = std::make_shared<MessageProcessorFactory>(handler_factory);

    auto transport_socket = std::make_shared<TServerSocket>(9090);
    auto transport_factory = std::make_shared<TFramedTransportFactory>();
    auto protocol_factory = std::make_shared<TBinaryProtocolFactory>();

    TThreadedServer server(processor_factory, transport_socket, transport_factory, protocol_factory);
    server.serve();
    return 0;
}

错误原因

MessageProcessorFactory是Thrift根据IDL文件自动生成的类,它的实现代码位于api/gen-cpp/Message.cpp中。当前CMakeLists.txt仅编译了server.cpp,未将生成的Message.cpp纳入编译流程,导致链接阶段找不到该类虚函数表(vtable)的定义,触发链接错误。

解决方法

步骤1:修改CMakeLists.txt,添加生成的源文件

将Thrift生成的Message.cpp添加到可执行文件的源列表,同时确保CMake能找到该文件路径:

cmake_minimum_required(VERSION 3.11)
project(server)

set(THRIFT_LIB_DIR "/home/konstantin/thrift/thrift-0.19.0")
# 指定生成代码的目录
set(GEN_CPP_DIR "${PROJECT_SOURCE_DIR}/api/gen-cpp")

find_library(THRIFT_LIB thrift ${THRIFT_LIB_DIR})

# 将生成的Message.cpp与server.cpp一同编译
add_executable(${PROJECT_NAME} 
    server.cpp
    "${GEN_CPP_DIR}/Message.cpp"
)

# 包含生成代码的头文件目录
target_include_directories(${PROJECT_NAME} PRIVATE ${GEN_CPP_DIR})

target_link_libraries(${PROJECT_NAME} ${THRIFT_LIB})

步骤2:重新构建项目

删除原有build目录,重新执行构建命令:

rm -rf build
mkdir build
cd build
cmake ..
make

修改后,编译流程会包含Message.cpp的代码,链接时即可找到MessageProcessorFactory的虚函数表定义,错误即可解决。

内容的提问来源于stack exchange,提问作者Behemoth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:16:04