i want to do this simple piece of code work.
#include <iostream>
#include <windows.h>
void printSome (int i)
{
std::cout << i << std::endl;
}
void spawnThread (void (*threadName)(int i))
{
CreateThread
(
0, // default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)threadName, // thread function name
(LPVOID)i, // argument to thread function
0, // use default creation flags
0 // returns the thread identifier
);
}
int main ()
{
spawnThread(printSome(155));
}
i am on windows, using vs. Any help will be greatly appriciated.
CreateThread wants 2 arguments: pointer to the function to execute as a thread, and a DWORD argument that will be given to the thread. your spawnThread() function only has 1 argument (threadName); you think it has 2 args because of the "i", but that is really part of the definition of the "threadName" type. (you could just as well leave out the "i"; that is, you don't need to name the arguments to "threadName".)
anyway, given that you NEED 2 arguments, redefine spawnThread:
void spawnThread(void (*threadEntryPoint)(int), int argument)
{
CreateThread(0,0,
(LPTHREAD_START_ROUTINE)threadEntryPoint,
(LPVOID)argument,
0,0);
}
notice that i did not name the int argument to the threadEntryPoint; it is sufficient to tell the compiler that the function must have a single int argument.
and call it:
spawnThread(printSome, 155);
anyway, quick and dirty, this will do what you want.
hth.
reilly.
Personally, I wouldn't consider passing in a function pointer like you are trying to do as very C++ like. That's coding C in C++
Instead, I'd wrap that thing in a class. The big advantage there is you can just override the class to have however many members you want, rather than having to perform greazy casting tricks to get at your parameters every time.
The code's a little long-winded, so I pushed it to the end. But what it lets you do is something like this:
class print_some : public basic_thread {
private:
int i;
public:
print_some (int i) : i(i) {};
action_callback () {
std::cout << i << std::endl;
}
}
int main () {
print_some printer (155);
}
Here's some exerpted example code from one of our classes that does this:
class basic_thread :
{
public:
basic_thread();
protected:
unsigned long m_ThreadId;
virtual void action_callback () {};
// Internal routine used to bridge between OS callback format and
// action_callback. *Must* be static for the OS.
static unsigned long __stdcall self_calling_callback (void *parameter);
}
...and in the .cpp:
unsigned long __stdcall basic_thread::self_calling_callback (void *parameter) {
if (parameter) {
basic_thread * thread = reinterpret_cast<basic_thread *>(parameter);
thread->action_callback();
}
return 0; // The value returned only matters if someone starts calling GetExitCodeThread
// to retrieve it.
}
basic_thread::basic_thread () {
// Start thread.
m_Handle = CreateThread(NULL,
0,
self_calling_callback,
(PVOID)this,
0,
&m_ThreadId );
if( !IsHandleValid() )
throw StartException("CreateThread() failed", GetLastError());
}
You cannot pass parameter information in a function pointer; it must be passed separately. That is exactly why the CreateThread function provides a void* parameter that can point to whatever you want.
Additionally, you should use _beginthread instead of CreateThread for C++ applications.
Finally, your program is more than likely to terminate before the thread ever runs. Therefore, you must either enter an indefinite loop or use an API call to wait for the thread to finish.
The following is a working version using WaitForSingleObject to block until the thread completes.
#include <iostream>
#include <process.h>
#include <windows.h>
void
printSome(int i)
{
std::cout << i << std::endl;
}
HANDLE
spawnThread(void (*threadName)(int), int i)
{
return (HANDLE) _beginthread((void (*)(void*)) threadName, 0, (LPVOID) i);
}
int
main(int argc, char *argv[])
{
HANDLE threadHandle;
threadHandle = spawnThread(printSome, 155);
WaitForSingleObject(threadHandle, INFINITE);
return 0;
}
Here is a much more C++/object-oriented way of handling this same situation:
#include <iostream>
#include <process.h>
#include <windows.h>
class Thread {
static void proxy(void *arg) { (*(reinterpret_cast<Thread *> (arg)))(); }
HANDLE thread_;
public:
virtual ~Thread() {}
virtual void operator()() = 0;
void start() { thread_ = (HANDLE) _beginthread(Thread::proxy, 0, this);}
void waitForExit() { WaitForSingleObject(thread_, INFINITE); }
};
class Printer : public Thread {
int i_;
public:
Printer(int i) : i_(i) {}
void operator()() { std::cout << i_ << std::endl; }
};
int
main(int argc, char *argv[])
{
Printer p(155);
p.start();
p.waitForExit();
return 0;
}
As many people already mentioned here, you can't pass a function pointer and the argument it should be called with in one parameter.
Your line
spawnThread(printSome(155));
"should" (in DWIM world) mean "Invoke printSome on a separate thread with argument 155". However, it's not how C++ understands it. C++ sees "Pass the result of printSome invoked on 155 as a parameter to spawnThread". In other words, the sequence of steps is:
call prinotSome with 155 as argument. Store it in temporary memory.
call spawnThread with the contents of temporary memory as its argument.
In order to do what you really mean, you have to humor C++ and separate argument from function. How to do it is already explained in other answers. The short of it is:
callOnOtherThreadWithArgument(function, integer);
You can read how you do that here: http://www.newty.de/fpt/fpt.html
2.6 How to Pass a Function Pointer as an Argument ?
You can pass a function pointer as a
function's calling argument. You need
this for example if you want to pass a
pointer to a callback function. The
following code shows how to pass a
pointer to a function which returns an
int and takes a float and two char:
//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer
// <pt2Func> is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b'); // call using function pointer
cout << result << endl;
}
// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
PassPtr(&DoIt);
}
Related
I have a C library which use this function prototype, I want to use it in C++
int mlx_key_hook(void *win_ptr, int (*funct_ptr)(), void *param);
but in reality the function asked is
int funct_ptr(int keycode, void *param);
In fact I have this problem: Why put void in params?
Then, I ask you how can I call this function with the appropriate C++ funct_ptr ?
Or have I to re-compil this lib after having changed the funct_ptr prototype ?
This doesn't work:
mlx_key_hook(win_ptr, [](int keycode, void *param) -> int {
return 0;
}, NULL);
This work but that's not what I want:
mlx_key_hook(win_ptr, []() -> int {
return 0;
}, NULL);
The best solution would be to recompile your C++ code with a header that uses an appropriate function prototype, i.e.
int mlx_key_hook(void *win_ptr, int (*funct_ptr)(int keycode, void *param), void *param);
Then the code snippet with a lambda that takes two parameters will compile.
Another solution would be to use reinterpret_cast. Although it is not allowed to call a function with a reinterpreted signature (undefined behavior) casting a reinterpreted pointer back to its original signature before the call is allowed.
typedef int (*funct_ptr_good)(int, void *);
typedef int (*funct_ptr_bad)();
void foo(funct_ptr_bad fb) {
// This is a C++ version of what your C library does
funct_ptr_good fg = reinterpret_cast<funct_ptr_good>(fb);
fg(12345, NULL);
}
int main() {
funct_ptr_good fg = [] (int key, void * ptr) -> int {
cout << key << " " << ptr << endl;
return 0;
};
// foo expects a pointer that takes no parameters, in the same way that your C library does
foo(reinterpret_cast<funct_ptr_bad>(fg));
return 0;
}
The above prints 12345 0 (demo).
typedef void (*CALLBACK)();
class Filter
{
public:
void callback()
{
cout << "callback" << endl;
}
};
void SetCallback(CALLBACK pCallBack )
{
pCallBack();
}
int main()
{
Filter f;
SetCallback(f.callback);
}
In main, SetCallback(f.callback); statement is giving error. Can anyone help me to fix the issue
The problem is that a member function isn't a plain function without parameters, because it always has the implicit this parameter.
If you encounter a legacy C interface that requires a plain callback function without a user context parameter (a void* that the function just passes on to the callback) you have a problem.
If you do have the user context, it's easy. Pass the object pointer as the context, and use a wrapper function as the actual callback:
typedef void (*CALLBACK)(void*);
class Filter
{
public:
static void CallbackWrapper(void* context) {
static_cast<Filter*>(context)->callback();
}
private:
void callback();
};
int main() {
Filter f;
SetCallback(&Filter::CallbackWrapper, &f);
}
If you don't have the context, here are some options:
Store the object in a global variable and access it from a wrapper. This has the obvious downsides of using a global variable, and not allowing more than one callback this way. For long-running callbacks this is really bad.
A small improvement to the above is to use a thread-local global variable. This is interesting for tightly scoped callbacks, e.g. you call a function that will immediately use your callback multiple times and then return. Think qsort(). At least this way, you don't get the thread safety issues. Still not an option for long-running callbacks.
Finally, the option that works on most platforms but is a lot of work, you can generate a stub function at runtime which embeds the object pointer. This basically means allocating a piece of memory, disabling execution protection on that memory if the platform uses this, and put machine code there that loads the object pointer and calls the function on it.
The final option still has lots of downsides: it's extremely platform-specific and may not even work at all on some (you can't disable execution protection in iOS, AFAIK), it's CPU-specific (since you need to generate the right code for each), and there's the issue of managing the memory for the stub. On the other hand, sometimes it's the only thing that works. Delphi does this kind of stuff for its window and hook procedures sometimes, and the ATL does so too.
Here is a method I've used to implement a callback to a pointer to member function.
It might require C++11.
#include <iostream>
#include <string>
#include <functional>
using namespace std;
struct MessageSource
{
function<void(const string& msg)> _callback;
template<typename A, typename B>
void connect(A func_ptr, B obj_ptr)
{
_callback = bind(func_ptr, obj_ptr, placeholders::_1);
}
void send_msg(const string& msg)
{
if (_callback)
_callback(msg);
}
void disconnect()
{
_callback = nullptr;
}
};
struct Printer
{
void print(const string& msg) { std::cout << msg << std::endl; };
};
int main()
{
{
Printer p;
MessageSource s;
s.connect(&Printer::print, &p);
s.send_msg("test");
s.disconnect();
s.send_msg("test again");
}
system("pause");
return 0;
}
A simplier example about callback for 'non-static method' :
#include <iostream>
#include <string>
#include <functional>
using namespace std::placeholders;
class Test
{
public:
void SetValue(int i) { v = i;}
int v;
};
int main()
{
Test a { 123 };
std::cout << a.v << std::endl; // print 123
auto _callback = std::bind(&Test::SetValue, &a, _1); // create the callback
_callback(55); // call the callback
std::cout << a.v << std::endl; // print 55
return 0;
}
output :
123
55
You should think about what a callback really is and how a member function is called.
When you give a callback function, you just give the address of a function that will later be called with parameters on which you normally have little control.
When a member function is called, its first parameter is the this pointer, that is a reference to the object on which the method is called.
That's the reason why it is not possible to use a member method as a callback. You can only use true functions or static member functions that do not need the special (implicit for programmer but real in a compiler point of view) parameter this.
I've the following code:
#include <iostream>
typedef void ( *FuncPtr )( int );
extern void MyFunc( FuncPtr callback )
class MyClass
{
public:
void SomeFunction( int n )
{
std::cout << "bla: " << n << std::endl;
}
};
int main()
{
MyClass obj;
MyFunc( /* */ );
}
What is the best and safety way to pass in MyFunc function as a parameter a function of class without (SomeFunction) boost?
You can't, and even if your compiler allows it, I'm sure you'd get into undefined behavior.
SomeFunction is not like a free function, it is a member function. That means it operates on an object, so calling it outside of context is a sure path to disaster.
The idiom for C callbacks is to include user data which passes an arbitrary parameter through the function and back into the callback:
typedef void ( *FuncPtr )( int, uintptr_t user_data );
extern void MyFunc( FuncPtr callback, uintptr_t user_data );
When invoking a method on a class with a callback you use the user_data to pass the this pointer:
class MyClass
{
public:
void SomeFunction( int n )
{
std::cout << "bla: " << n << std::endl;
}
private:
static void SomeFunctionEntry( int n, uintptr_t user_data)
{
MyClass *ths = (MyClass *) user_data;
ths->SomeFunction(n);
}
};
The static function SomeFunctionEntry is a free function which can be invoked as a callback. You ensure its user_data argument is a valid class instance:
int main()
{
MyClass obj;
MyFunc(&MyClass::SomeFunctionEntry, (uintptr_t) &obj);
}
(side note: it is a very bad idea to pass an automatic variable like obj as a callback in a multithreaded environment because it is difficult to be sure that the pointer will still be valid when the callback is eventually invoked)
I want the Windows thread pool (QueueUserWorkItem()) to call my class' member functions.
Unfortunately this cannot be done directly by passing a member function pointer as an argument to QueueUserWorkItem().
What makes it difficult is that more than one member function must be callable and they have different signatures (all return void though).
One probably need to add a few layers of abstraction to get this to work, but I'm not sure how to approach this. Any ideas?
This might help.
You can use tr1::function () and tr1::bind to "coalesce" various calls:
#include <iostream>
#include <tr1/functional>
using namespace std;
using namespace tr1;
class A
{
public:
void function(int i) { cout << "Called A::function with i=" << i << endl; }
};
void different_function(double c) {
cout << "Called different_function with c=" << c << endl;
}
int main(int argc, char* argv[])
{
function<void()> f = bind(different_function, 3.14165);
f();
A a;
f = bind(&A::function, a, 10);
f();
return 0;
}
The address of the function object can be passed as a single callable object (needing only one address).
Example:
In your class add:
char m_FuncToCall;
static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
{
myclass* _val = (myclass*)myclassref;
switch(m_FuncToCall)
{
case 0:
_val->StartMyOperation();
break;
}
return 0;
}
Make a member for adding to queue then
void myclass::AddToQueue(char funcId)
{
m_FuncToCall=funcId;
QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
}
or create
typedef void (*MY_FUNC)(void);
typedef struct _ARGUMENT_TO_PASS
{
myclass* classref;
MY_FUNC func;
}ARGUMENT_TO_PASS;
and then
void myclass::AddToQueue(MY_FUNC func)
{
ARGUMENT_TO_PASS _arg;
_arg.func = func;
_arg.classref = this;
QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}
If you need further explanation feel free to ask :)
EDIT: You'll need to change the ThreadStartRoutine for the second example
and you can also change the struct to hold the passing argument
I'm trying to create a function that will store and repeat another function given as a parameter for a specific amount of time or repeats given.
But when you want to pass a function as a parameter you have to know all of its parameters before hand.
How would I do if I wanted to pass the function as one parameter, and the parameters as another?
void AddTimer(float time, int repeats, void (*func), params); // I know params has no type and that (*func) is missing parameters but it is just to show you what I mean
Thanks in advance
The best that you can do is use std::function or boost::function as argument, together with std::bind or boost::bind to, well, bind the arguments with the function:
void foo() { std::cout << "foo" << std::endl; }
void bar( int x ) { std::cout << "bar(" << x << ")" << std::endl; }
struct test {
void foo() { std::cout << "test::foo" << std::endl; }
};
void call( int times, boost::function< void() > f )
{
for ( int i = 0; i < times; ++i )
f();
}
int main() {
call( 1, &foo ); // no need to bind any argument
call( 2, boost::bind( &bar, 5 ) );
test t;
call( 1, boost::bind( &test::foo, &t ) ); // note the &t
}
Note that there is something inherently wrong with passing a fully generic function pointer: how do you use it? How would the body of the calling function look like to be able to pass an undefined number of arguments of unknown types? That is what the bind templates resolve, they create a class functor that stores the function pointer (concrete function pointer) together with copies of the arguments to use when calling (note the &t in the example so that the pointer and not the object is copied). The result of the bind is a functor that can be called through a known interface, in this case it can be bound inside a function< void() > and called with no arguments.
dribeas' answer is correct as far as modern C++ is concerned.
For the sake of interest, there's also a simple lo-tech solution from the C world that as far as it goes, works in C++. Instead of allowing arbitrary parameters, define the function as void (*func)(void*), and make "params" void*. It's then the caller's job to define some struct that will contain the parameters, and manage its lifecycle. Usually the caller would also write a simple wrapper to the function that's really needed to be called:
void myfunc(int, float); // defined elsewhere
typedef struct {
int foo;
float bar;
} myfunc_params;
void myfunc_wrapper(void *p) {
myfunc_params *params = (myfunc_params *)p;
myfunc(params->foo, params->bar);
}
int main() {
myfunc_params x = {1, 2};
AddTimer(23, 5, myfunc_wrapper, &x);
sleep(23*5 + 1);
}
In practice you want to "fire and forget" timers, so if you use this scheme you may also need a way for the timer manage to free the userdata pointer once all firings have completed.
Obviously this has limited type safety. In principle in shouldn't matter, because whoever supplies the function pointer and user data pointer shouldn't have a great deal of difficulty ensuring that they match. In practice of course people find ways to write bugs, and ways to blame you because their compiler didn't tell them about the bugs ;-)
It's just an example how you could pass function pointer to another function, and then call it:
void AddTimer(float time, int repeats, void (*func)(int), int params)
{
//call the func
func(params);
}
void myfunction(int param)
{
//...
}
AddTimer(1000.0, 10, myfunction, 10);
Similarly, you can write your code if your function takes different type or/and numbers of parameters!
If there's really no rules about the function pointer at all, just use void*.
In C++11, things get really simple - you get everything you need to implement your timers.
The most concise way of passing bound function calls is by passing a functor generated using lambda syntax, e.g.: []{ std::cout << "Hello, world!" << std::endl; }. An object thus generated has a type known only to the compiler, but the type is convertible to std::function<void()>.
#include <functional>
#include <list>
#include <chrono>
#include <thread>
#include <iostream>
template <typename Clock = std::chrono::high_resolution_clock>
class Timers {
public:
using clock = Clock;
using duration = typename clock::duration;
using time_point = typename clock::time_point;
private:
struct Timer {
duration const period;
std::function<void()> const call;
int repeats;
time_point next;
Timer(duration $period, int $repeats, std::function<void()> && $call) :
period($period), call(std::move($call)), repeats($repeats) {}
};
std::list<Timer> m_timers;
public:
Timers() {}
Timers(const Timers &) = delete;
Timers & operator=(const Timers &) = delete;
template <typename C> void add(std::chrono::milliseconds period,
int repeats, C && callable)
{
if (repeats) m_timers.push_back(Timer(period, repeats, callable));
}
enum class Missed { Skip, Emit };
void run(Missed missed = Missed::Emit) {
for (auto & timer : m_timers) timer.next = clock::now() + timer.period;
while (! m_timers.empty()) {
auto next = time_point::max();
auto ti = std::begin(m_timers);
while (ti != std::end(m_timers)) {
while (ti->next <= clock::now()) {
ti->call();
if (--ti->repeats <= 0) {
ti = m_timers.erase(ti);
continue;
}
do {
ti->next += ti->period;
} while (missed == Missed::Skip && ti->next <= clock::now());
}
next = std::min(next, ti->next);
++ ti;
}
if (! m_timers.empty()) std::this_thread::sleep_until(next);
}
}
};
int main(void)
{
Timers<> timers;
using ms = std::chrono::milliseconds;
timers.add(ms(1000), 2, []{ std::cout << "Hello, world!" << std::endl; });
timers.add(ms(100), 20, []{ std::cout << "*" << std::endl; });
timers.run();
std::cout << std::endl;
return 0;
}