1

尝试编译一个非常简单的类建模 TCP 服务器时,我遇到了一个奇怪的链接器错误。我已将其缩小到我试图调用的一行代码operator=(std::thread&&);我调用移动运算符,因为复制构造函数被标记为=delete.

这是我第一个使用 std::thread 和 C++11 的项目,所以也许我在做一些愚蠢的事情,有什么想法吗?

我列出了代码、编译器选项和编译器输出。

clang++ -g -Weverything -Wall -std=c++11 -stdlib=libc++ -Wno-c++98-compat -Wno-weak-vtables -I../ -I/usr/local/include Main.cpp -c -o Main.o
clang++ -g -Weverything -Wall -std=c++11 -stdlib=libc++ -Wno-c++98-compat -Wno-weak-vtables -I../ -I/usr/local/include deepthgt/AdminHandler.cpp -c -o deepthgt/AdminHandler.o

clang++ -stdlib=libc++ -L/usr/local/boost_1_50_0/stage/lib -L/usr/local/lib -lboost_program_options -lboost_thread -lboost_system -lglog Main.o deepthgt/AdminHandler.o  -o bets42
Undefined symbols for architecture x86_64:
  "std::__1::__any::__any(...)", referenced from:
      __ZNSt3__114__thread_proxyINS_5tupleIJMN6bets428deepthgt12AdminHandlerEFvvENS_17reference_wrapperIS4_EEEEEEEPvSA_ in AdminHandler.o
  "__ZNSt3__18__invokeIJNS_17reference_wrapperIN6bets428deepthgt12AdminHandlerEEEEEENS_5__natENS_5__anyEDpOT_", referenced from:
      __ZNSt3__114__thread_proxyINS_5tupleIJMN6bets428deepthgt12AdminHandlerEFvvENS_17reference_wrapperIS4_EEEEEEEPvSA_ in AdminHandler.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [bets42] Error 1

//---

    class AdminHandler : private boost::noncopyable
    {
         public:
            explicit AdminHandler(const unsigned short port);
            ~AdminHandler();

            void start();
            void stop();

        private:
            void handle();

        private:
            std::thread thread_;
            std::mutex  mutex_;
            bool        doHandle_;
            const unsigned short port_;
    };    

//----

AdminHandler::AdminHandler(const unsigned short port)
    : doHandle_(false),
      port_(port) {}

AdminHandler::~AdminHandler()
{
    stop();
}

void AdminHandler::start()
{
    std::lock_guard<std::mutex> lock(mutex_);
    if( ! thread_.joinable())
    {
        doHandle_ = true;
        thread_ = std::move(std::thread(&AdminHandler::handle, std::ref(*this))); //this code here is the problem
    } 
}

void AdminHandler::stop()
{
    std::lock_guard<std::mutex> lock(mutex_);
    if(thread_.joinable())
    {
        doHandle_ = false;
        thread_.join();
    }
}

void AdminHandler::handle()
{
    try
    {
        using boost::asio::ip::tcp;

        boost::asio::io_service service;
        tcp::acceptor acceptor(service, tcp::endpoint(tcp::v4(), port_));

        do
        {
            tcp::socket socket(service);
            acceptor.accept(socket);

            boost::system::error_code error;
            boost::asio::write(socket, boost::asio::buffer("hello world!"), error);
        } 
        while(doHandle_); 
    }
    catch(const std::exception& e)
    {
        boost::throw_exception(
                Exception(__FILE__, __LINE__) 
                << "Failed to start or continue to listen on admin port " << port_
                << "; exception: " << e.what()
        );
    } 
}
4

1 回答 1

1

尝试:

thread_ = std::move(std::thread(&AdminHandler::handle, this));

正在研究这是否是 libc++ 错误...

于 2012-08-31T23:53:02.240 回答