0

I am trying to connect a simple UDP reader with a thread, so that when UDP reader class is created, it initializes a thread that reads stuff from the socket and processes the data. The code does not show any issues in the IDE, but when I attempt to compile it, I get the following Errors:

Error   C2064   term does not evaluate to a function taking 0 arguments (thread.hpp, line 116)

When I check it for more details, my IDE shows me an issue with the thread.hpp's get_id() function:

Error (active)      declaration is incompatible with "boost::thread::id boost::this_thread::get_id()" (thread.hpp, line 665).

I am not sure what to do with this actually, one thing I did not expect to see is errors in the header files. Please help.

This is my class code:

class networkUDPClient {
public:
    const char * hostAddress;
    unsigned int port;

    void (*customFunction)(void ** args);
    void ** argumentPointers;

    utilityTripleBuffer * buffer;

    boost::asio::io_service service;
    boost::asio::ip::udp::socket socket;
    boost::asio::ip::udp::endpoint listenerEndpoint;
    boost::asio::ip::udp::endpoint senderEndpoint;

    boost::thread_group * threads = new boost::thread_group();

    boost::thread * readThread;
    boost::thread::id readThreadID;

    // Function Definitions
    void readCallback(const boost::system::error_code & error, std::size_t read_bytes) {
        this->customFunction(this->argumentPointers);
    };

    void readSocket(void) {
        while (1) {
            this->socket.async_receive_from(
                boost::asio::buffer(
                    this->buffer->currentBufferAddr,
                    this->buffer->bufferSize),
                senderEndpoint,
                0,
                boost::bind(
                    &networkUDPClient::readCallback,
                    this,
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred));
        }
    }

    void startReadProcess(void) {
        this->service.run();

        this->threads->create_thread(&networkUDPClient::readSocket);

        this->readThreadID = this->readThread->get_id();
    }

    void stopReadProcess(void) {
        this->threads->join_all();
            this->threads->~thread_group();

        this->socket.close();

        this->service.stop();
    }

    // Constructors
    networkUDPClient(const char * hostAddress, unsigned int port, void (*customFunction)(void ** args), void ** argumentPointers) :
        socket(service),
        listenerEndpoint(boost::asio::ip::address_v4::from_string(hostAddress), port)
    {
        this->buffer = (utilityTripleBuffer*)argumentPointers[0];

        this->customFunction = customFunction;
        this->argumentPointers = argumentPointers;

        this->hostAddress = hostAddress;
        this->port = port;

        socket.open(this->listenerEndpoint.protocol());
        socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
        socket.bind(this->listenerEndpoint);

        this->startReadProcess();
    };
    ~networkUDPClient()
    {
        this->stopReadProcess();
    };
};

Any criticism on my implementation of the threading for UDP purposes is also welcome.

  • Is that the *full* and *complete* error message? There's nothing else which leads back to a line in your code? – Some programmer dude Feb 09 '18 at 06:49
  • Oh and you have a few other problems as well. For example where do `readThread` point? Try to avoid pointers as much as you can. – Some programmer dude Feb 09 '18 at 06:52
  • The error message points exactly where it mentions, the file and the line (I removed the path to my computer directories for privacy reasons). The readThread variable is unused, I was thinking about doing it the long way (making a thread, then adding it to the thread group). I might use it later, once I resolve this issue. Thanks for noticing. – AdmiralFishHead Feb 09 '18 at 07:02
  • 1
    Your constructor calls `startReadProcess` which calls `readThread->get_id()`. So no it's not unused. – Some programmer dude Feb 09 '18 at 07:08
  • 1
    Sorry to say, but you have the same problem as your last question https://stackoverflow.com/q/48673558/8918119. on the line `this->threads->create_thread(&networkUDPClient::readSocket);` you cannot pass non-static member finction use `bind()` or pass `this` as argument. and lok whether your `get_id()` issue appear again. – Mihayl Feb 09 '18 at 08:20
  • Also `this->threads->~thread_group();`? call `delete` or use `unique_ptr` – Mihayl Feb 09 '18 at 08:25
  • `while (1) { sock.async_xxx(); }` is probably a bad idea. If you are using the async API your thread should probably only do `io_service.run()`. – sbabbi Feb 09 '18 at 09:12
  • @A.A I was using the example given in this link, which states that the boost thread automatically binds any function it needs. https://stackoverflow.com/questions/13742648/creating-a-boostthread-with-boostbind-or-without-it – AdmiralFishHead Feb 09 '18 at 13:38
  • @sbabbi This was how I tried to make the async_read_from function non blocking, so that I can make an object with it's own thread and forget about it until I need to remove it. – AdmiralFishHead Feb 09 '18 at 13:48

1 Answers1

0

You cannot pass non-static member function to boost::thread_group::create_thread() use bind() or lambda and look whether your get_id() issue appears again.

this->threads->create_thread(boost::bind(&networkUDPClient::readSocket, this));

Demo

The create_thread() documentation says:

Create a new boost::thread object as-if by new thread(threadfunc) and add it to the group.

but this is the single parameter constructor of the boost::thread class taking thread(F f); only a Callable, not the variadic template that binds also the arguments:

template <class F,class A1,class A2,...>
    thread(F f,A1 a1,A2 a2,...);
Mihayl
  • 3,821
  • 2
  • 13
  • 32
  • Like I posted in my comment, the `thread()` function automatically binds any function it needs. I tried something like you posted before, and it did not work. I used your code as well, also didn't work. Here's the source: https://stackoverflow.com/questions/13742648/creating-a-boostthread-with-boostbind-or-without-it – AdmiralFishHead Feb 09 '18 at 13:42
  • @AdmiralFishHead, I updated my answer `boost::bind(&networkUDPClient::readSocket, this)` without the `_1` works. – Mihayl Feb 09 '18 at 15:25