Using c++ 11 multithreading on non-static member function - c++

So, my problem is this:
I have a class called NetworkInterface that is built using the RakNet networking library.
It holds a method that uses the while loop that RakNet uses to send and receive data.
Now, I made the NetworkInterface class a singleton because I want it to only exist once throughout my game I'm writing.
But, if I'd just call the method with the while loop it would stop my whole gqme so thqt's why I wanted it to run on a different thread so it doesn't interfere with the game mechanics.
Now, I used the std::thread object to start the method in NetworkInterface on a different thread but it throws the C3867 error which states that the method needs to be static or some sort (I found this on Google already) but I don't know how to fix this because I have variables that are used in that method that can't be static as well.
I hope this is clear. In short, how would I implement a non-static method from a class in a seperate thread of my program. Or is there a better way? (I don't want to use the Boost library if that pops up)

You need to provide an object for you to call a non-static member function, just as you can't call method() on its own. To provide that object, pass it to std::thread's constructor after the argument where you put the function.
struct Test {
void func(int x) {}
};
int main() {
Test x;
std::thread t(&Test::func, &x, 42);
t.join();
}
LIVE EXAMPLE
Notice that I've passed &x. This is because non-static class functions accepts a pointer to the object where it is being called from, and this pointer is the this pointer. The rest, which is 42, is the arguments that corresponds to the method's parameter declaration with 42 coinciding with int x in the example.

Related

How would I use a library that extends libev in a C++ object?

I am trying to implement a wrapper for a library called libumqtt. Libumqtt is a C library that uses libev to have callbacks for events from the MQTT protocol.
What I didn't realize until the other day is that I cannot pass a member function to a function that expects a normal, static function. This causes problems as I was planning on launching multiple instances of libumqtt to handle multiple connections at the same time.
My code is in C++ as that is the most convenient to use with the Godot's (a game engine) GDNative module.
While researching for either a way to sandbox multiple instances of a c library or to somehow get the pointers to work anyway, I found this answer. I do not understand this quote from the answer:
If you need to access any non-static member of your class and you need
to stick with function pointers, e.g., because the function is part of
a C interface, your best option is to always pass a void* to your
function taking function pointers and call your member through a
forwarding function which obtains an object from the void* and then
calls the member function.
What I am trying to do is setup callbacks that libev will use to send the data to the right instance of my object when it is handling potentially up to 500 or more connections simultaneously.
Will passing void* help me with my goals and how would I implement this? Also, how does a forwarding function work?
Edit: To Provide Code Example That Walnut Is Asking For
This example below comes from a version of my class that uses static functions. If I tried to use run this when the functions are not static, then I would get an error about not being able to pass in a member function in place of a regular function.
// Client.cpp
void Client::signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
ev_break(loop, EVBREAK_ALL);
}
// ...
void Client::do_connect(struct ev_loop *loop, struct ev_timer *w, int revents) {
//Godot::print("Attempt MQTT Start!!!\n");
//write_log("debug", "MQTT Wrapper - Attempt MQTT Start!!!");
struct umqtt_client *cl; // Move to Class Access (Private)?
cl = umqtt_new(loop, cfg.host, cfg.port, cfg.ssl);
if (!cl) {
//Godot::print("Failed To Create Client!!!\n");
//write_log("debug", "MQTT Wrapper - Failed To Create Client!!!");
start_reconnect(loop);
return;
}
//Godot::print("Setup Client Callbacks!!!\n");
//write_log("debug", "MQTT Wrapper - Setup Client Callbacks!!!");
// For StackOverflow: These cl->... lines do not work because of not being able to pass a member function as a regular function. These are the main callbacks I have trouble with.
// How do I convert from `void (libumqtt::Client::*)(struct umqtt_client *)` to `void (*)(struct umqtt_client *)`?
cl->on_net_connected = Client::on_net_connected; // Pass member function as a non-static object
cl->on_conack = Client::on_conack; // Pass member function as a non-static object
cl->on_suback = Client::on_suback; // Pass member function as a non-static object
cl->on_unsuback = Client::on_unsuback; // Pass member function as a non-static object
cl->on_publish = Client::on_publish; // Pass member function as a non-static object
cl->on_pingresp = Client::on_pingresp; // Pass member function as a non-static object
cl->on_error = Client::on_error; // Pass member function as a non-static object
cl->on_close = Client::on_close; // Pass member function as a non-static object
//Godot::print("MQTT Start!!!\n");
//write_log("debug", "MQTT Wrapper - MQTT Start!!!");
}
void Client::initialize() {
// For StackOverflow: These two lines cannot work in an object as libev expects signal_cb and do_connect to be regular functions. These callbacks are also necessary, but I am not sure how to handle this.
ev_signal_init(&signal_watcher, Client::signal_cb, SIGINT);
ev_timer_init(&reconnect_timer, Client::do_connect, 0.1, 0.0); // Fix Me - Make ev.h object
// ...
}
Edit: I should mention I am a noob at using C and C++. The most I've done in it before is testing a buffer overflow. So, if their's anything I am obviously doing wrong, I would appreciate the tip in the comments.
So the issue is that umqtt_client does not seem to provide any way of passing additional user data to the callback (the void* mentioned in your quote). It expects the callback to take just a pointer to the umqtt_client instance. (I may be wrong here, I am basing this just on a quick look at the source files.)
If your member functions don't actually access any non-static member of your class, then you can simply make them static. Then you can use them directly as normal function pointers.
Otherwise you need to obtain a pointer to your instance from the umqtt_client* pointer.
One way of doing this would be to maintain a static map between the pointers, e.g. in Client add a declaration:
static std::map<umqtt_client*, Client*> umqtt_client_map;
and insert into it when creating a Client (I will assume here that you actually maintain the cl pointer as class member of Client), preferably in Client's constructor:
umqtt_client_map[cl] = this;
Then in Client's destructor (or where ever the umqtt_client object is destroyed) erase the corresponding element from the map:
umqtt_client_map.erase(cl);
Then you can use a lambda looking like this to pass as callback:
cl->on_net_connected = [](umqtt_client* ptr){
umqtt_client_map[ptr]->on_net_connected();
};
Note that on_net_connected won't need the pointer as argument if it is a member of the class.
This also assumes that you make the class non-copyable and non-movable or that you implement the copy- and move-constructor and -assignment operators with the correct semantics of erasing and inserting into umqtt_client_map as well.
The library seems to offer a function umqtt_init instead of umqtt_new that doesn't allocate the umqtt_client object. If you use that instead you could do the following:
Wrap the umqtt_client in a small standard-layout class:
struct umqtt_client_wrapper {
umqtt_client cl; // must be first member!
Client* client;
static_assert(std::is_standard_layout_v<umqtt_client_wrapper>);
};
You would then use that as member of Client instead of umqtt_client* directly and initialize the umqtt_client* with umqtt_init) andclientwiththisinClient`'s constructor. Then you can use a cast in the lambda for the callback:
cl->on_net_connected = [](umqtt_client* ptr) {
reinterpret_cast<umqtt_client_wrapper*>(ptr)->client->on_net_connected();
};
Note that this depends on umqtt_client_wrapper being standard-layout and that umqtt_client* is its first member. Not following these rules will cause undefined behavior. The static_assert gives some assurance that at least part of it is not accidentally violated. It requires #include<type_traits> and C++17 in the form that I used here.
Again this requires special care to implement the copy- and move- special member functions of Client correctly or to delete them, but with this method no action in the destructor is required.
This approach is more performant than the other one and in principle you could avoid the extra Client pointer if you make sure that Client itself is standard-layout, but that is probably too restrictive and risky.
Another way, saving the extra indirection, is to use the wrapper as a base class of Client:
struct umqtt_client_wrapper {
umqtt_client cl; // must be first member!
static_assert(std::is_standard_layout_v<umqtt_client_wrapper>);
};
Then let Client inherit from umqtt_client_wrapper and you can use:
cl->on_net_connected = [](umqtt_client* ptr) {
static_cast<Client*>(reinterpret_cast<umqtt_client_wrapper*>(ptr))
->on_net_connected();
};
Note that here the first cast must be static_cast, otherwise you could easily cause undefined behavior.
The same remarks as before apply.

c++11 thread, static or non-static class member function, meaning of arguments

I have been playing with the c++11 thread for a while, and have some questions. People say that when you call a class member function in thread, this function has to be static. But it seems that this is not true. For example, I found this:
class bar
{ public:
void foo() {std::out << "Hello" << std::endl};
}
int main()
{
std::thread t0(&bar::foo, bar());
t0.join();
}
The above code works fine. It seems that the member function do not have to be static in c++11 standard. I want to know if my understanding is true. Another question is that, if I simply modify "void foo()" with "static void foo()", I get an error:
error: no type named 'type' in 'class std::result_of<void (*(bar))()>'
I do not understand this, but it seems that this is because the way I call the thread is not correct. I am very confuse in calling a function in a thread. For example, I found another way to call the same member function in the above example as
int main()
{ bar A;
std::thread t0(&bar::foo, &A);
}
It works also! I don't know the difference between these two ways. It seems that in the first way the constructor of the class will be performed each time I call foo(), while the in the second one it will not. Is that true? Besides, when calling member function in another class member function, the 'this' has to be passed.
I search the internet, all I can find is examples, without explaining the meaning of the arguments. Can anyone tell me how should I set the arguments (especially the first three) in a std::thread?
std::thread t0(&bar::foo) works pretty fine with static foo method.
Also, when asking a question consider to provide working code but not your text what you actually wrote just now right in the text field of this site.
Short answer to your question: provide this parameter to non-static class methods or don't provide it if it is static class method.
But, if you don't understand even that you must know one thing:
each class method works with this object which means a constant pointer to current object. While binding your function (I guess exactly binding works inside std::thread) the first parameter must be the object which method you want to call. Otherwise it is meaningless: you are trying to do something with what object then? The this exists in each non-static method of the class, implicitly, by first parameter of the method.
I recommend you to read the definitive c++ stackoverflow book guide and list

Pass a non-static method pointer as an argument to another method

Sorry to ask such a question as I'm sure it's been answered before, but I'm struggling to find an answer and it's not for the want of looking... anyway..
class foo
{
void read(void (*func)(obj&))
{
// many things happen to obj...
(*func)(obj); // Calls the function pointer to the handler.
}
};
class bar : public foo
{
void handler(obj&)
{
//
}
};
void main()
{
foo f;
typedef void (foo::*funcptr)(obj&);
funcptr ptr = &foo::handler;
f.read(ptr); ????
}
So basically, all I'm trying to do is pass the non-static member method called handler as a function pointer to the read method, so that when the callback is executed, the handler is called.
I've tried all sorts of ways to make this work and don't want to make static methods (for reasons I won't go into). I think I'm pretty close, but have sort of fallen over right at the end! Any help would be appreciated.
You cannot do that: unlike static functions that can be called on their own, the call of a member function requires knowledge of two things - the function being called, and the object on which to call it. That is why it is not possible to pass a member function to an API expecting a "plain" function pointer.
If you do not have access to the source of the foo class, you can create a static function that calls a member function on an object stored at a well-known location (i.e. in a static variable). If you do, consider changing the API to take a function object, similar to what functions from the standard C++ library do.
Finally, there is a common approach used in C libraries that take function pointers - passing an additional void* pointer, which will be passed back in a call to your function pointer; pthreads library does that. If this is the case, you can create a struct that wraps the invocation target object, and pass a pointer to this struct to be passed back to your static function.
AFAIK I don't think there is any other way. You will have to make the method static.

ATMega32 C++ Object in Timer Interrupt

Is there a possibility to call a member function, say the output over UART, to be triggered by an interrupt?
Normally I would have used the TIMER0_COMP vect but I can't seem to get it to work with objects.
SomeClass theObject;
// ...
ISR(USART_RX_vect)
{
theObject.someMethod();
}
Is this what you're looking for?
There is no way to have an interrupt vector point to a specific object's member function. This is due to the fact that it is not possible to pass the *this pointer to an ISR directly.
It is possible to have the interrupt vector point to a specific class's member function, provided that it is a static function that returns void and has no parameters. However, as it's a static function it has no access to any individual object's non-static data members.
Here's an example for an IAR compiler and a timer interrupt vector from an AVR:
class theClass
{
public:
...
#pragma vector=TCC1_CCA_vect
__interrupt static void isrTimer1CompareA(void);
...
}
Again, the limitations with this approach are that the ISR can only access static data for the class.
If you're looking to have the interrupt to relate to a specific object, you'll need something along the lines of what H2C03 recommends, which is having the ISR know about the specific object, then calling a member of that object in the ISR itself.

Creating a boost::thread with boost::bind() or without

Some people seem to launch boost::threads using the boost::bind() function, like in the accepted answer of the following question:
Using boost thread and a non-static class function
Whereas other people don't use it at all, like in the answer with the most upvotes of this question:
Best way to start a thread as a member of a C++ class?
So, what's the difference, if it exists?
As you can see by the code below that compile and gives the expected output, boost::bind is completely unnecessary for using boost::thread with free functions, member functions and static member functions:
#include <boost/thread/thread.hpp>
#include <iostream>
void FreeFunction()
{
std::cout << "hello from free function" << std::endl;
}
struct SomeClass
{
void MemberFunction()
{
std::cout << "hello from member function" << std::endl;
}
static void StaticFunction()
{
std::cout << "hello from static member function" << std::endl;
}
};
int main()
{
SomeClass someClass;
// this free function will be used internally as is
boost::thread t1(&FreeFunction);
t1.join();
// this static member function will be used internally as is
boost::thread t2(&SomeClass::StaticFunction);
t2.join();
// boost::bind will be called on this member function internally
boost::thread t3(&SomeClass::MemberFunction, someClass);
t3.join();
}
Output:
hello from free function
hello from static member function
hello from member function
The internal bind in the constructor does all the work for you.
Just added a few extra comments on what happens with each function type. (Hopefully I've read the source correctly!) As far as I can see, using boost::bind externally will not cause it to also double up and be called internally as it will pass through as is.
There is no difference - thread contructor uses bind internally.
People use bind explicitly for historical reasons, because Boost.Thread didn't have a "binding" constructor before 1.36.
The boost::bind is used to bind a member function to a thread, whereas without boost::bind normally you're using a static function or a free function with the thread.
So, what's the difference, if it exists?
The main difference is what do you need to access within the thread function.
If your design requires that you access a class instance's data, then launch your thread as part of a class instance (use boost::bind with this and a member function, or a static member function with a void* mapped to this - that's a matter of style mostly).
If your design requires that the thread function is not dependent on a particular object's data, then use a free function.
The primary difference is whether you want to interface static or non-static member functions. If you want to use non-static member functions as the function launched by the thread, you must use something like bind.
The proposed alternative (the second question you linked) is to use a static method that takes a pointer to the class object and can then call any of it's members. This clears up the syntax slightly but the biggest advantage (to me) is that you don't need to include something like Boost to get bind. But if you are using boost::threads you might as well take boost::bind also. Note, C++ 11 has std::bind so you could use bind with pthreads as well and not introduce any extra dependency such as Boost, but that's if you want to use C++ 11.
I don't see a compelling syntax reason to avoid using bind over having a static method that calls member functions. But that is more a matter of personal preference.