How can I cast or convert boost bind to C function pointer?
Suppose I have this:
void func(WCHAR* pythonStatement) {
// Do something with pythonStatement
}
And I need to convert it to void function(void) like this:
bind(func, TEXT("console.write('test')"))
Now I have struct like this:
typedef void (__cdecl * PFUNCPLUGINCMD)();
struct FuncItem {
PFUNCPLUGINCMD pFunc;
// ...
};
How can I set the pFunc of my struct to bind(func, "something")
? Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer?
Thanks.
Ende开发者_高级运维d up using the wrapping "solution" (GitHub)
I think that you can't, unless you make the resulting lamba_functor a global variable.
In that case, you could declare a function that invokes it:
void uglyWorkaround() {
globalLambdaFunctor();
}
and set pFunc
to uglyWorkaround()
.
EDIT
Just a sidenote: if you are binding static text to the function call, you may completely omit bind()
call and write just:
void wrapper() {
func(TEXT("console.write('test')"));
}
and set pFunc
to wrapper()
.
Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer?
I don't think you can. However, off the top of my head, I can think of several alternatives:
Use
boost::function<void()>
(orstd::function()
if your compiler supports TR1 or C++11) instead ofvoid (*)()
.
It has the ability to bind to just about anything with a somewhat compatible signature.Put the whole code into a template, make
PFUNCPLUGINCMD
a template parameter, and let function template argument deduction figure out the exact type. That's a variation on the former, actually, where you would use the result ofbind()
directly instead of havingboost::function
abstract away the gory details.Create a wrapper that calls the functor returned by
boost::bind()
.
A function template might help to let the compiler figure out the exact types and generate a suitable function, although I haven't tried to do that. However, since you cannot use the result ofbind()
as a template argument, but need to have give the function access to it nevertheless, you will need a global variable for this. (The ability to avoid this is one of the main advantages of function objects, a very versatile of which isstd::function
.)Extend your
PFUNCPLUGINCMD
callback type to support a user-provided parameter. For C callbacks, this usually is avoid*
. However, if you pass the address of the object returned bybind()
to your callback, you would need to convert it into a pointer to the correct type - which, AFAIK, depends on the arguments provided tobind()
. In order to avoid that, you'd need to pass something that abstracts away the exact type. Again,std::function
comes to the rescue.
The first idea would be the best, but it requires you to be able to change PFUNCPLUGINCMD
. The last one might be best when PFUNCPLUGINCMD
needs to be compatible with C, as it uses the common C callback idiom.
You can't do this, unless you want to write your own Just-In-Time compiler. Alternatively, if you control the receiving code, then you could use a boost::function<>
, which will accept a variety of function types, including pointers and function objects like those produced by boost::bind
.
精彩评论