Using C++.
pthread_t threads[STORAGE]; // 0-99
...
void run()
Error>>> int status = pthread_create(&threads[0], NULL, updateMessages, (void *) NULL);
if (status != 0)
{
printf("pthread_create returned error code %d\n", status);
exit(-1);
}
...
void ClientHandler::updateMessages(void *)
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
...
Compile Error:
TCPClient.cpp:109: error: argument of type ‘void (ClientHandler::)(void*)’ does not match ‘void* (*)(void*)’
I can't figure out whats wrong.
Thanks in advance.
A pointer to a member function is different from a global function with the same signature since the member function needs an additional object on which it operates. Therefore pointers to these two types of functions are not compatible.
In this case this means that you cannot pass a member function pointer to pthread_create but only a pointer to a non-member (or static) function. A work around for this problem is to use the forth parameter of pthread_create to pass a pointer to a object to a global function which then calls the method of the passed object:
class ClientHandler {
public:
void updateMessages();
void run();
};
// Global function that will be the threads main function.
// It expects a pointer to a ClientHandler object.
extern "C"
void *CH_updateMessages(void *ch) {
// Call "real" main function
reinterpret_cast<ClientHandler*>(ch)->updateMessages();
return 0;
}
void ClientHandler::run() {
// Start thread and pass pointer to the current object
int status = pthread_create(&threads[0], NULL, CH_updateMessages, (void*)this);
...
}
It's nothing to do with threads, it's a normal C++ error, you're just passing an incompatible type of function pointer.
A function pointer is not the same as a member instance function pointer, even if their signature is the same; this is because there is an implicit reference to *this passed. You can't avoid this.
As pthread_create takes a free function, create a static function(is a free function) inside ClientHandler
static void Callback(void * this_pointer,int other_arg) {
ClientHandler* self = static_cast< ClientHandler*>(this_pointer);
self-> updateMessages(other_arg);
}
and call pthread_create as follows
pthread_create(&threads[0], NULL, &ClientHandler::Callback, (void *) pointer_to_ClientHandler,int other_arg);
That works because Callback is free function
YoLinux has a nice pthread tutorial that my help you in learning about threads.
As others have already said, the problem is that the signatures between the functions are different. Class member functions always have a "secret" extra parameter, the this pointer. So you can never pass a member function where a global function is expected. You can hack around this either with libraries such as Boost.Bind, or by making the function a static member of the class.
But the simplest, and most elegant solution is to use a different threading API.
Boost.Thread is a very nice threading library for C++ (pthreads is designed for C, and that's why it doesnt play well with C++ features such as class methods).
I'd recommend using that.
Your code could be rewritten as something like this:
class ClientHandler {
public:
ClientHandler(/* All the parameters you want to pass to the thread. Unlike pthreads you have complete type safety and can pass as many parameters to this constructor as you like */){...}
void operator()() // boost.thread calls operator() to run the thread, with no parameters. (Since all parameters were passed in the constructor and saved as member variables
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
// whatever arguments you want to pass to the thread can be stored here as member variables
};
boost::threead_group gr; // can store all your threads here, rather than being limited to your fixed-size array
gr.create_thread(ClientHandler(/* construct a ClientHandler object with the parameters you like*/));
You're passing a member function instead of a global, normal, one.
Just define:
void updateMessages(void *) {
static ClientHandler c;
// use c..
}
Related
I haven't used C++ in ages. Between what I've forgotten and what has changed in C++ over time, I'm really banging my head against the wall trying to do something that would be trivially easy in JavaScript, or any other language where functions are objects, and not just simple pointers.
I think I understand the basic problem: A class member function only exists in once place in memory (there isn't a different copy of it for each class instance). The only way the function knows what "this" is is because an instance pointer is passed along as an invisible first argument to every function call. A plain-old C-style callback isn't going to know anything about passing that instance pointer.
What I need is a new function that is somehow bound to my class instance, one which knows how to pass "this" along to the member function. That's the function I need to use as a callback.
But I don't know for sure how to dynamically create such a function. I think the code below is on the right track (except for casting pointer types), but it does bother me a bit because it seems like that there'd have to be some dynamic memory allocation going on, and if so, some way to track that allocation and do clean-up later.
class SignalMonitor {
int dataPin;
unsigned short timings[RING_BUFFER_SIZE];
unsigned long lastSignalChange = 0;
int dataIndex = 0;
int syncCount = 0;
void signalHasChanged();
public:
SignalMonitor(int);
};
SignalMonitor::SignalMonitor(int dataPin) {
this->dataPin = dataPin;
function<void()> callback = bind(&SignalMonitor::signalHasChanged, this);
wiringPiISR(dataPin, INT_EDGE_BOTH, callback);
}
void SignalMonitor::signalHasChanged() {
unsigned long now = micros();
int duration = (int) min(now - this->lastSignalChange, 10000ul);
this->lastSignalChange = now;
cout << duration << '\n';
}
I feel like this is close to what I want, but I'm getting this error:
acu-rite-433Mhz-reader.cpp:58:72: error: invalid cast from type ‘std::function<void()>’ to type ‘void*’
wiringPiISR(dataPin, INT_EDGE_BOTH, reinterpret_cast<void *>(callback));
^
Here's the call signature of the function I'm trying to pass this callback to:
int wiringPiISR (int pin, int edgeType, void (*function)(void))
I've found a number of similar issues discussed when searching on this topic, but they either don't quite match what I'm trying to do, or assume much more familiarity with C++ than I currently possess. (All I remember about function pointer types is that they can get hellishly ugly very quickly!)
I tried to use lambda function as a solution, but that led to an error (besides a type mismatch error) about something being "temporary", which I'm assuming meant that the lambda function's scope was temporary.
This is a far from ideal solution (I'm beginning to think there are no ideal solutions here), but it works for me in this particular case where there aren't likely to be very many instances of my SignalMonitor class in use at the same time.
First, I turned my signalHasChanged class method into a static method that takes an instance as an argument. (I could have kept the method as a class method by going through some hairy type-casting, but it wasn't worth it.)
Then I made ten almost-identical indirect callback functions:
void smCallback0() { SignalMonitor::signalHasChanged(monitors[0]); }
void smCallback1() { SignalMonitor::signalHasChanged(monitors[1]); }
void smCallback2() { SignalMonitor::signalHasChanged(monitors[2]); }
void smCallback3() { SignalMonitor::signalHasChanged(monitors[3]); }
void smCallback4() { SignalMonitor::signalHasChanged(monitors[4]); }
void smCallback5() { SignalMonitor::signalHasChanged(monitors[5]); }
void smCallback6() { SignalMonitor::signalHasChanged(monitors[6]); }
void smCallback7() { SignalMonitor::signalHasChanged(monitors[7]); }
void smCallback8() { SignalMonitor::signalHasChanged(monitors[8]); }
void smCallback9() { SignalMonitor::signalHasChanged(monitors[9]); }
Then I stuck all of those functions into an array:
void (*_smCallbacks[MAX_MONITORS])() = {
smCallback0, smCallback1, smCallback2, smCallback3, smCallback4,
smCallback5, smCallback6, smCallback7, smCallback8, smCallback9
};
Along with the monitors array, which is an array of SignalHandler pointers, this gives me ten available callback slots. (_smCallbacks is copied into smCallbacks as a way to get around foreward reference problems.)
The init method for SignalMonitor simply searches for an available slot, plugs itself in, then sets the callback:
void SignalMonitor::init() {
for (int i = 0; i < MAX_MONITORS; ++i) {
if (monitors[i] == NULL) {
callbackIndex = i;
monitors[i] = this;
break;
}
}
if (callbackIndex < 0)
throw "Maximum number of SignalMonitor instances reached";
wiringPiISR(dataPin, INT_EDGE_BOTH, smCallbacks[callbackIndex]);
}
There's also a destructor to free up the callback slots:
SignalMonitor::~SignalMonitor() {
if (callbackIndex >= 0)
monitors[callbackIndex] = NULL;
}
It may help to consider the traditional way of handling a similar issue. Other APIs have been designed where instead of void(*function)(void), wiringPiISR would expect a function void(*function)(void *). This allows the use of
static void signalHasChanged(void *p) {
static_cast<SignalMonitor*>(p)->signalHasChanged();
}
This is not a general solution, but because Raspberry Pi has a limited number of GPIO pins, and you can't have more callback functions than you have pins, you might be able to create one callback function per pin. Then, you need a global data structure that maps the interrupt pin to which SignalMonitor instance (or instances) it should signal. The constructor would register the 'this' object to a specific pin, then set the appropriate callback function based on the pin.
The callback functions would be able to pass a pin argument to a general function, which could then look up the specific SignalMonitor instance and call a class function.
I wouldn't want to do it for 1000 pins, 1000 instances, but this hack should work for anything running on a Pi.
is there a possibility or a workaround to pass a member function to the Windows API function QueueUserAPC()?
Okay, I could pass a static member function.
But then I won't have full access to local member variables...
So is there a possibility to combine both, passing as member function and full access to non-static member variables?
I tried to work out a solution related to this but without any success yet.
Hopefully someone got an idea to solve this.
This is a kind of standard pattern to use when having C-style callbacks call your C++ functions.
You create a free function (or static member) that forwards the call ...
VOID CALLBACK ForwardTo_MyClass_func( _In_ ULONG_PTR dwParam )
{
auto* p = (MyClass*)dwParam;
p->func();
}
... and you then set it up by passing the instance pointer as the third parameter to QueueUserAPC:
QueueUserAPC( ForwardToMyClass_func, hThread, (ULONG_PTR)pMyClass );
If you need further arguments, you will have to create some kind of structure to hold both the instance pointer and the arguments.
The answer is no.
Windows API has a C interface, and therefor cannot handle name mangled signatures, such as C++ member functions. The function you pass must be a C style free function.
By the way, nesting it in a namespace is acceptable, if less scalable:
namespace apc_stuff
{
static MyStruct some_static_data;
static void __stdcall MyApcFunc(ULONG_PTR data); // PAPCFUNC
};
using namespace apc_stuff;
MyClass::DoSomething(...)
{
auto my_data = new MyData(...);
auto data = reinterpret_cast<ULONG_PTR>(my_data);
QueueUserAPC(MyApcFunc, hThread, data)
}
/*static*/ void __stdcall apc_stuff::MyApcFunc(ULONG_PTR data)
{
auto my_data = reinterpret_cast<MyData *>(data);
//
// use my_data
// use some_static_data
//
}
I am using libusb to interact with a usb device. I have created a Class and a member function will receive the input from the device and process it. I am using Asynchronous api. Now the libusb_fill_bulk_transfer() function call throws a compilation error:
void MyDeviceClass::on_connectButton_clicked()
{
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize the library for the session we just declared
if(r < 0) {
qDebug()<<"Init Error "<<r<<endl; //there was an error
return;
}
...
...
...
libusb_fill_bulk_transfer( transfer_in, dev_handle, USB_ENDPOINT_IN,
inBuffer, LEN_IN_BUFFER,readDataFromBuffer,NULL,0);
libusb_submit_transfer(transfer_in);
QtConcurrent::run (this,&MyDeviceClass::eventThread);
}
The compiler suggests using &MyDeviceClass::readDataFromBuffer as a function pointer but that still throws an error. I tried using static members, and even static non-member functions but all in vain. Please help me in passing the callback to this function. I am using Qt, and probably won't like to use boost libraries.
Please note that libusb_fill_bulk_transfer(...) is invoked inside a member function of MyDeviceClass.
I made the member function static and prototype needed to be modified:
static void LIBUSB_CALL readDataFromBuffer(struct libusb_transfer *);
what is the compile error when you use a non member function?
Edit: this should be LIBUSB_CALL:
void LIBUSB_CALL BulkTransferCallback(struct libusb_transfer *transfer) {
// This assumes that you set transfer::user_data to be a pointer to
// an instance of the MyDeviceClass class.
MyDeviceClass* mdc = reinterpret_cast<MyDeviceClass*>(transfer->user_data);
mdc->onBulkTransferCallback(transfer);
}
Then when you set the pointer, use:
transfer.callback = &BulkTransferCallback;
As you answered yourself, actually it should be __stdcall which is defined by LIBUSB_CALL. Their documentation should include this in the function pointer typedef to remove the ambiguity.
The lib_usb api defines the function libusb_fill_bulk_transfer with:
static void libusb_fill_bulk_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *buffer, int length, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
It is possible to add a static class function to your class and call the non-static member-function
of the class within this static function.
You this Object would be at the place of void *user_data.
In the static class function you would have to cast the member of
transfer->user_data correctly to your class.
I have got a main function like this:
int main(){
....
Protocol SPI_conn;
SPI_conn.omap_SPI_init();
....
pthread_create(&rt_OneStep0_thread, NULL, rt_OneStep0, NULL);
....
}
where SPI_conn is an object of the class Protocol and omap_SPI_init() is a method of the same class. My thread-function looks like this:
extern "C" void * rt_OneStep0(void *)
{
while (1) {
sem_wait(&step0_semaphore);
SPI_do();
sem_wait(&step0_semaphore);
}
}
SPI_do() is also a function of the class Protocol. My question is, how can I use the object SPI_conn with the method SPI_do. Normally you can do it by reference, but here rt_OneStep0(void*) has to be defined like this, right?
I really appreciate your help!
Absolutely, your prototypes are correct.
It all lies in how you can use the last parameter of pthread_create. It's actually a pointer to anything you want, that will be passed as the parameter to your thread's entry point (so, here, rt_OneStep0).
Hence, if you create your thread like this :
pthread_create(&rt_OneStep0_thread, NULL, rt_OneStep0, &SPI_conn);
You will receive the address of your SPI_conn object as the void* argument of your rt_OneStep0 function. You'll just have to cast it back to the proper type and you can then use it normally.
extern "C" void * rt_OneStep0(void *arg)
{
Protocol *my_object = static_cast<Protocol*>(arg);
//...
}
However, since you're dealing with threads and you'll be sharing an object created on your main thread, be careful about concurrency and race conditions.
I'm a little confused about how to pass an object to the pthread_create function. I've found a lot of piecemeal information concerning casting to void*, passing arguments to pthread_create, etc., but nothing that ties it all together. I just want to make sure I've tied it all together and am not doing anything stupid. Let's say I have the following thread class:
Edit: fixed mis-matched static_cast.
class ProducerThread {
pthread_t thread;
pthread_attr_t thread_attr;
ProducerThread(const ProducerThread& x);
ProducerThread& operator= (const ProducerThread& x);
virtual void *thread_routine(void *arg) {
ProtectedBuffer<int> *buffer = static_cast<ProtectedBuffer<int> *> arg;
int randomdata;
while(1) {
randomdata = RandomDataGen();
buffer->push_back(randomdata);
}
pthread_exit();
}
public:
ProtectedBuffer<int> buffer;
ProducerThread() {
int err_chk;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);
err_chk = pthread_create(&thread, &thread_attr, thread_routine, static_cast<void *> arg);
if (err_chk != 0) {
throw ThreadException(err_chk);
}
}
~ProducerThread() {
pthread_cancel(&thread);
pthread_attr_destroy(&thread_attr);
}
}
To clarify, the data in the ProtectedBuffer class can only be accessed with methods like ProtectedBuffer::push_back(int arg), which use mutexes to protect the actual data.
My main question is: am I using static_cast correctly? And my secondary question is do I need that first line in virtual void *thread_routine(void *arg) where I copy the passed void pointer to a pointer to ProtectedBuffer?
Also, if I've done anything else that might cause problems, I'd appreciate hearing it.
There are a number of problems with your code. For starters, I don't
see where the arg you are casting is declared, so I can't say whether
the case is appropriate.
Perhaps more importantly, thread_routine is a member function, so it
can't be converted to a pointer to a function. The function passed to
pthread_create must be extern "C", so it cannot be a member, period;
it must be a free function declare extern "C". If you want to call a
member function, pass a pointer to the object as the last argument, and
dereference it in the extern "C" function:
extern "C" void* startProducerThread( void* arg )
{
return static_cast<ProducerThread*>( arg )->thread_routine();
}
And to start the thread:
int status = pthread_create( &thread, &thread_attr, startProducerThread, this );
Just don't do this in a constructor. The other thread might start
running before the object is fully constructed, with disasterous
effects.
Also, be very sure that the cast in startProducerThread is to
exactly the same type as the pointer passed into pthread_create. If
you cast to a base class in startProducerThread, then be very, very
sure that it is a pointer to that base class that you pass to
pthread_create; use an explicit cast if necessary (to the type in
startProducerThread, not to void*).
Finally, while not relevant to your actual question: if
ProtectedBuffer has an interface like that of std::vector, and
returns references to internal data, there's no way you can make it
thread safe. The protection needs to be external to the class.
If you want to go this route, I believe you want something like this:
Edit: Based on James Kanze's answer, add a separate activate method to launch the thread after construction is finished.
class GenericThread {
protected:
GenericThread () {
//...
}
virtual ~GenericThread () {}
int activate () {
return pthread_create(..., GenericThreadEntry, this);
}
virtual void * thread_routine () = 0;
#if 0
// This code is wrong, because the C routine callback will do so using the
// C ABI, but there is no guarantee that the C++ ABI for static class methods
// is the same as the C ABI.
static void * thread_entry (void *arg) {
GenericThread *t = static_cast<GenericThread *>(arg);
return t->thread_routine();
}
#endif
};
extern "C" void * GenericThreadEntry (void *) {
GenericThread *t = static_cast<GenericThread *>(arg);
return t->thread_routine();
}
Then, ProducerThread would derive from GenericThread.
Edit: Searching for extern "C" in the C++ Standard. revealed no requirement that a function pointer must point to a function with C linkage to be callable by a C library routine. Since pointers are being passed, linkage requirements do not apply, as linkage is used to resolve names. A pointer to a static method is a function pointer, according to C++ 2011 draft (n3242), Sec. 3.9.2p3:
Except for pointers to static members, text referring to pointers does not apply to pointers to members.
Edit: Mea culpa. The C library will invoke the callback function assuming the C application binary interface. A function with C++ linkage may use a different ABI than the C ABI. This is why it is required to use a function with extern "C" linkage when passing to a callback function to a C library. My sincere apologies to James Kanze for doubting him, and my sincere thanks to Loki Astari for setting me straignt.