Calling a class member function from a thread using pthread_create - c++

Below is the code
#include <iostream>
#include <pthread.h>
using namespace std;
class Base
{
private:
public:
void *threadCall1( void * value)
{
cout<<"inside threadCall1"<<endl;
}
protected:
};
class Derived
{
private:
public:
void *threadCall2 ();
protected:
};
void *Derived::threadCall2()
{
cout<<"inside threadCall2"<<endl;
}
int main ()
{
int k = 2;
pthread_t t1;
cout<<"inside main"<<endl;
Base *b = new Base();
pthread_create(&t1,NULL,&b->threadCall1,(void *)k);
return 0;
}
Error
main.cc: In function int main()': main.cc:46: error: ISO C++ forbids
taking the address of a bound member function to form a pointer to
member function. Say&Base::threadCall1' main.cc:46: error: cannot
convert void*(Base::*)(void*)' tovoid*()(void)' for argument 3'
toint pthread_create(pthread_t*, const pthread_attr_t*,
void*()(void), void*)'
I agree C++ forbids this call but is there any way I can call a class member function using posix thread

You can do this via a function that dispatches the work accordingly:
#include <iostream>
#include <pthread.h>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
void* thread_adapter(void* obj) {
Base* p = static_cast<Base*>(obj);
p->work();
return nullptr;
}
int main() {
Derived d;
pthread_t thread;
pthread_create(&thread, nullptr, thread_adapter, &d);
pthread_join(thread, nullptr);
}
Live example
pthread_create accepts a pointer to arbitrary data for the thread function. Pass the address of your object, and use a forwarding function such as the thread_adapter defined above. Inside the adapter function, you can static_cast the argument back to a Base* inside your thread function and invoke the member function as desired.
However, you may want to look into the std::thread library, which supports such operations in a more natural way:
#include <iostream>
#include <thread>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
int main() {
Derived d;
std::thread t(&Base::work, d);
t.join();
}
Live example

There's no such thing as &b->threadCall1. Fortunately, pthread allows you to pass a void ptr to the class (the one you're filling with k). Pass b as this void ptr to a global (or static member) function that simply calls b->threadCall1(); then move k to an attribute of Base instead of an argument of Base::threadCall1().

You cannot use pointer to member function as thread routine. Consider to use thead context structure to pass need information to the thead routine:
struct thread_context {
Base* object;
void (Base::*func)(void*);
};
void *thread_routine(void *arg) {
thread_context* context = static_cast<thread_context*>(arg);
context->object->(*context->func)(nullptr);
...
}
...
thread_context context = {
b1,
&Base::threadCall1
};
pthread_create(&t1,NULL,&thead_routine, &context);

Related

Callable being required to be static in C++ class template

I would like to have the following class setup in a program:
A class that implements a buffer. This buffer, when full, would spawn a thread that makes a callback to handle what to do with the full buffer.
A base class template that includes a buffer object. Implements the callback function, which makes a call to a virtual function defined in a derived class.
A derived class that inherits from base class and implements what to do with the data.
First, the minimal reproducible example:
#include <vector>
#include <iostream>
#include <thread>
template <typename T>
class CallbackBuffer
{
public:
std::vector<T> buffer;
void (*callback)(std::vector<T>);
std::thread writerThread;
CallbackBuffer(int bufferSize = 10)
{
buffer.resize(bufferSize);
}
void setCallback(void (*cb)(std::vector<T>))
{
callback = cb;
}
void writeCall()
{
writerThread = std::thread(callback, buffer);
}
};
template <typename T>
class Base
{
public:
CallbackBuffer<T> buffer;
Base()
{
buffer.setCallback(bufferHandler);
}
void bufferHandler(std::vector<T> v)
{
for(auto &i : v)
{
write(i);
}
}
virtual void write(T i) = 0;
};
class Derived : public Base<int>
{
public:
Derived()
{
}
void write(int i)
{
std::cout << i << std::endl;
}
};
int main()
{
Derived d;
return 0;
}
I'm getting the following compiler error:
error: invalid use of non-static member function ‘void Base<T>::bufferHandler(std::vector<T>) [with T = int]’
So the compiler needs bufferHandler to be static, but if I did that, then I would not have access to the object's members. Is there a way to sort this, or just a horrible idea?
You are passing the class member function so you need to have in your CallbackBuffer class something like:
void (Base<T>::*callback)(std::vector<T>);
// ...
void setCallback(void (Base<T>::*cb)(std::vector<T>)) {
callback = cb;
}
and in Base class:
Base() {
buffer.setCallback(&Base<T>::bufferHandler);
}
Demo
Member function pointers have different type than regular functions, that's why your code does not work. What you may want is using std::function instead of raw pointers:
#include <functional>
//...
std::function<void(std::vector<T>)> callback;
// ...
void setCallback(const std::function<void(std::vector<T>)>& cb) {
callback = cb;
}
and pass it like that:
Base() {
buffer.setCallback([this](auto& vec){ this->bufferHandler(vec); });
}
IMHO this is much more readable and flexible than passing around member pointers

pthread without static decelaration with class

Inside the class I declared the thread function. I used static keyword because with out static keyword it is not working with class.
But if the type of the function is static I could not able to access the member function and public variables of the class
#include <iostream>
#include <pthread.h>
using namespace std;
class Base{
private:
static void * fpga_read(void*); // Thread function
void foo_2();
public:
/* member variables */
void foo(void);
protected:
int b;
};
void Base::foo(void)
{
pthread_t id;
pthread_create(&id, NULL,fpga_read,NULL);
cout << "\nInside base class" << endl;
}
void * Base::fpga_read(void *p)
{
cout << "\nInside thread function " << endl;
// error: invalid use of member ‘Base::b’ in static member function
cout << "Value of B inside thread class" << b;
int b;
}
int main()
{
Base a;
a.foo();
pthread_exit(NULL);
return 0;
}
Any-body tell me how to use thread function with-out static keyword. so i can able to access all class variables.
You do not need any static member function. You can use the argument parameter of pthread_create and that stateless lambda functions decay to normal function pointers to make code which almost looks like what you actually wrote:
Godbolt link: https://godbolt.org/z/QIGNUX
#include <iostream>
#include <pthread.h>
class Base {
public:
Base(int state) noexcept : b{state} {}
void foo();
private:
int b;
void fpga_read() {
std::cout << "Value of B inside thread class" << b;
}
};
void Base::foo()
{
pthread_t thread;
pthread_create(&thread, nullptr, [](void* that) -> void* {
Base* this_ = static_cast<Base*>(that);
this_->fpga_read();
return nullptr;
}, static_cast<void*>(this));
pthread_join(thread, nullptr);
}
pthread_create, like all OS-specific thread creation APIs (CreateThread etc in Windows) has a "void*" parameter to pass to the thread function.
You can use this to pass a pointer to your class
class A
{
void ThreadToUse() {}
static void Thread2(void* p)
{
A* a = (A*)p;
p->ThreadToUse();
}
void foo()
{
pthread_create(&A::Thread2,(void*)this);
}
};
That said, you can use C++11 std::thread with the same functionality as well in a standard way:
void foo()
{
std::thread t(&A::Thread2,this);
}

how to use a method of a c++ class as a callback function

I am trying to use a class's method as a callback function in another class in Qt. This is what I want to do:
Class A: public QObject
Q_OBJECT
public:
virtual void callBackFunc() = 0;
}
Class B: public A {
public:
B();
~B();
void callBackFunc() {
emit signal1();
}
}
Class C : public QObject {
Q_OBJECT
private:
A* m_b;
public:
C() {
m_b = new B();
}
~C();
void func() {
otherFunc(1,2,m_b->callBackFunc); // An API provided by an external library: otherFunc(int,int,void (*function)(void));
}
}
The above code doesn't compile. It throws the following error:
cannot convert 'A::callBackFunc' from type 'void (A::)()' to type 'void
(*)()
How can I call callBackFunc in func() method of class C within otherFunc()?
If your API takes a void (*function)(void), you cannot pass it a void (*A::function)(void).
First one is a function, the second one is a class method (which needs an object to be used on). Only static class methods (which are like functions) could be used here.
Alternatively, you could use global static variables to identify the object on which callBackFunc has to be called. But be very carefull with that (C::func must not be called recursively or from different threads...).
static B* objectToCallFuncOn = NULL;
void globalFunc()
{
assert( objectToCallFuncOn );
objectToCallFuncOn->callBackFunc();
}
void C::func()
{
objectToCallFuncOn = m_b;
otherFunc(1,2,&globalFunc);
objectToCallFuncOn = NULL;
}
As previous answer already said, a class method requires a this ptr. One way of doing it is with capturing 'this' with a C++11 lambda. Here is one example:
Callback with lambda capturing 'this' ptr
First of all, you can't pass a c++ style member function pointer to c style function pointer directly, but indirectly, there are two ways to achieve a goal.
static member method
The c++ member function's address is based on the instance, it is
this + offset
so every member method must has this pointer, the compiler did this.
Class B: public A {
public:
B();
~B();
void callBackFunc() {
emit signal1();
}
}
B b;
b.callBackFunc();
it is amount to
callBackFunc(&b)
this is why your compiler occurs an error.
The static member method doesn't need "this" pointer, so you can pass it to c style function, just like #jpo38 said.
thunk
what is thunk? you can find it in the source of WTL. The conclusion is, you can use thunk pack "this" pointer. Here is an case(reference page)
//main.cpp
#include <iostream>
#include <Windows.h>
#include <process.h>
#include "Thunk.h"
#include "resource.h"
using namespace std;
/////////////////////////////////////////////////////////
//第一个:__cdecl 回调类型
/////////////////////////////////////////////////////////
typedef int (__cdecl* CB)(int n);
void output(CB cb)
{
for(int i=0; i<3; i++){
cb(i);
}
}
class ACDCEL
{
public:
ACDCEL()
{
void* pthunk = m_Thunk.Cdeclcall(this,&ACDCEL::callback);
::output(CB(pthunk));
}
private:
int __cdecl callback(int n)
{
cout<<"n:"<<n<<endl;
return n;
}
private:
AThunk m_Thunk;
};
/////////////////////////////////////////////////////////
//第二个:__stdcall 回调类型:封装窗口类
/////////////////////////////////////////////////////////
class ASTDCALL
{
public:
ASTDCALL()
{
void* pthunk = m_Thunk.Stdcall(this,&ASTDCALL::DialogProc);
DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)pthunk,0);
}
private:
INT_PTR CALLBACK DialogProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
EndDialog(hWnd,0);
return 0;
}
return 0;
}
private:
AThunk m_Thunk;
};
/////////////////////////////////////////////////////////
//第三个:__stdcall 回调类型:内部线程
/////////////////////////////////////////////////////////
class AThread
{
public:
AThread()
{
void* pthunk = m_Thunk.Stdcall(this,&AThread::ThreadProc);
HANDLE handle = (HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall*)(void*))pthunk,(void*)5,0,NULL);
WaitForSingleObject(handle,INFINITE);
CloseHandle(handle);
}
private:
unsigned int __stdcall ThreadProc(void* pv)
{
int i = (int)pv;
while(i--){
cout<<"i="<<i<<endl;
}
return 0;
}
private:
AThunk m_Thunk;
};
int main(void)
{
ASTDCALL as;
ACDCEL ac;
cout<<endl;
AThread at;
return 0;
}

Pass method as callback from one class to other class

I have 2 class, I would like to pass a method from one to other by callback!
See that I also wish to hold the address of this method using void (*callBack)();
I'm used to do this in C, but I dont know how to do this in c++;
#include <iostream>
using namespace std;
class A
{
private:
void (*callBack)(); //to hold the address of the method
public:
A();
void setCallBack(void(*cB)());
void useCallBack();
};
A::A()
{
}
void A::setCallBack(void(*cB)())
{
callBack = cB;
}
void A::useCallBack()
{
callBack();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(someMethod);
Aguy->useCallBack()
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}
The problem is that:
void (*callBack)();
This is not a pointer to a method. This is a pointer to a function.
To have a pointer to a method you need to specify the class the method is in.
void (B::*callBack)();
Then when you call it you need to call it via an object.
void A::useCallBack(B* b)
{
(b->*callBack)();
}
But this is probably not what you want.
What you really want is a wrapper that encapsulates all this.
I would take a look at std::function. This will allow you to wrap a method call and an object into a single object that you can then call.
std::function<void()> callback;
Just replace all your occurrences of void(*cB)() with std::function<void()> then you can bind an instance of the object to the method at the call point.
Aguy->setCallBack(std::bind(&B::someMethod, this));
This also allows you to seemly pass any normal function or functor as a callback.
void print()
{ std:cout << "It worked\n";
}
...
Aguy->setCallBack(&print);
struct Printer
{
void operator()() const
{
std::cout << "It worked with obejct\n";
}
}
...
Aguy->setCallBack(Printer());
If you need to pass member function pointers see the modified code. it uses modern c++ constructs.
#include <iostream>
#include <functional>
using namespace std;
class A
{
private:
typedef std::function<void()> some_void_function_type;
some_void_function_type f_;
public:
A();
void setCallBack(some_void_function_type f);
void useCallBack();
};
A::A()
{
}
void A::setCallBack(some_void_function_type f)
{
f_ = f;
}
void A::useCallBack()
{
f_();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(std::bind(&B::someMethod, this));
Aguy->useCallBack();
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}
See c++ - <unresolved overloaded function type> for details.
To quote the answer:
In C++, member functions have an implicit parameter which points to
the object (the this pointer inside the member function). Normal C
functions can be thought of as having a different calling convention
from member functions, so the types of their pointers
(pointer-to-member-function vs pointer-to-function) are different and
incompatible. C++ introduces a new type of pointer, called a
pointer-to-member, which can be invoked only by providing an object.
Put static on someMethod:
class B
{
private:
A * Aguy;
public:
B();
static void someMethod();
void otherMethod();
};
void B::otherMethod() {
Aguy->setCallBack(B::someMethod);
Aguy->useCallBack(); // adding missing semicolon
}

Assign pointer to a function the address of a pointer to function object

Is it possible in C++?
For example I have a pointer to a function that takes no parameters and its return type is void:
void (*f)();
and and a function object:
class A
{
public:
void operator()() { cout << "functor\n"; }
};
Is it possible to assign to f the address of an A object? And when I call f() to call the A functor?
I tried this but it doesn't work:
#include <iostream>
using namespace std;
class A
{
public:
void operator()() { cout << "functorA\n"; }
};
int main()
{
A ob;
ob();
void (*f)();
f = &ob;
f(); // Call ob();
return 0;
}
I get C:\Users\iuliuh\QtTests\functor_test\main.cpp:15: error: C2440: '=' : cannot convert from 'A *' to 'void (__cdecl *)(void)'
There is no context in which this conversion is possible
Is there any way to achieve this?
You can't do it in the way you've specified, because:
operator() must be a nonstatic function (standards requirement)
a pointer to a non-static function must have an implicit parameter - the pointer to the class instance
your call to f() does not give any indication on which instance of the object A your function is called
Using C++11 and std::function, as Stephane Rolland pointed out, may do the trick - you'll be specifying the pointer to the object in the binding:
std::function<void(void)> f = std::bind(&A::operator(), &ob);
(See question on using std::function on member functions)
If you use C++11, could use std::function
#include <functional>
std::function<void()> f;
int main()
{
A ob;
ob();
f = ob; // f refers to ob
f(); // Call ob();
return 0;
}
Yes it's kind of possible using a C++1/C++0x feature, but to achieve this you should use the std::function which can address to the two types, functions and object functions.
#include <functional>
class A
{
public:
void operator()() { }
};
int main()
{
std::function<void(void)> aFunction;
A ob;
aFunction = ob;
// or as another user said
// aFunction = std::bind(&A:operator(), &ob);
aFunction();
void (*f)();
aFunction = f;
aFunction();
return 0;
}
and if you're stuck with C++03, you could play with std::mem_fun and std::ptr_fun
How about some workaround like this:
Basically you want to have a common way of calling member functions and functions. Then maybe you could create a wrapper that would represent a generic pointer to either a function or member function. Let's say you have Base class and you want to be able to invoke operator() of all derived classes. Then you also have a function() that you want to invoke as well:
class Base
{
public:
virtual void operator()() = 0;
};
class A : public Base
{
public:
void operator()(){ std::cout << "A()" << std::endl; }
};
void function()
{
std::cout << "function" << std::endl;
}
If you create an wrapper that allows you to construct your custom pointer (MyFncPtr):
typedef void (Base::*BaseFncPtr)();
typedef void (*FncPtr)();
class MyFncPtr
{
public:
MyFncPtr(FncPtr f) : fnc(f), baseObj(NULL), baseFnc(NULL) { }
MyFncPtr(BaseFncPtr fPtr, Base* objPtr) : baseFnc(fPtr), baseObj(objPtr), fnc(NULL) { }
void invoke()
{
if (baseObj && baseFnc)
(baseObj->*baseFnc)();
else if (fnc)
fnc();
}
private:
BaseFncPtr baseFnc;
Base* baseObj;
FncPtr fnc;
};
you could achieve it like this:
A a;
MyFncPtr myPtr(&Base::operator(), &a);
myPtr.invoke();
MyFncPtr myPtr2(function);
myPtr2.invoke();
outputs:
A()
function
Hope this helps :)