I have a class that handles all communication with a particular piece of hardware. The hardware requires data updates via one socket, and broadcasts its IP for handshaking purposes on a known (and hardcoded) multicast address.
As a result, the class spawns two threads, one thread which handles direct communication with the hardware and updates the data based on a member structure of the class. The other thread continuously monitors the multicast address to see if the IP has changed.
Both threads are implemented as static member functions inside the class. However, in order to use pthreads, my understanding is that they need to be declared as extern "C." That said, based on my research it is not possible to declare member functions of a class as extern "C." The way I saw some code from the engineer who worked on the project previously get around this problem is that the threaded function implementation is surrounded in extern "C." That is, extern "C" is not found in the function declaration or definition, but the whole function definition is encapsulated in extern "C" {}.
Like this:
extern "C" {
// function goes here
}
I have several questions about this implementation as I look to improve on my understanding of the code and become better at multithreaded programming.
Does the extern "C" actually do anything given the way it is implemented? I've read about what the modifier actually does here: In C++ source, what is the effect of extern "C"? but in this case is it actually applicable given the fact that we are dealing with functions that are static members of a class?
The threaded member functions seem to get around the fact of modifying the class's member variables by doing a reinterpret_cast and creating a pointer to the class. Is this standard practice, because my red flag was raised when I saw that cast?
The constructor calls pthread_create() to launch the threads. I was planning on doing something like adding a static member variable which only allows one instance to communicate with the hardware at any given time. That is, I was thinking about allowing the caller to have multiple instances of the class, but only one "connected" at a time. Is this standard practice, or is there something "hacky" in my way of thinking? There will only ever be one piece of hardware attached at a given time, so there is only the requirement to have one class instance operational at a given time.
Thanks for all your help. Also, if you are just going to suggest something like "Dude, just use Boost threads, FTW," please save your breath. Although I will eventually move to a threading library, my understanding is that Boost just wraps pthreads on POSIX systems. As a result, I want to learn about using the raw threads first before I spoil myself with a library. While my main goal is delivering on time, no one said that I couldn't learn anything along the way. ;)
Edited to add:
Here's some source code describing the issue that I'm seeing for clarity. I'm still not 100% sure that the extern "C" is doing anything in this case...
In my .h:
class MyClass
{
private:
static void* ThreadFunc(void* args); // extern "C" not found in declaration
static bool instance_;
};
In my .cpp:
MyClass::MyClass() {
if (!instance_) {
instance_ = true;
// spawn threads here
} else {
// don't spawn threads and warn user
}
}
extern "C" {
void *MyClass::ThreadFunc(void* args) { //definintion wrapped in extern C
MyClass* myclass_ptr = static_cast<MyClass*>(args);
// ... more code
return static_cast<void*> 0;
}