[英]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: 我需要将它转换为void function(void),如下所示:
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")
? 如何将我的struct的pFunc设置为
bind(func, "something")
? Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer? 绑定返回lambda_functor而不是函数指针,那么如何将此函子转换为函数指针?
Thanks. 谢谢。
Ended up using the wrapping "solution" (GitHub) 结束使用包装“解决方案” (GitHub)
I think that you can't, unless you make the resulting lamba_functor a global variable. 我认为你不能,除非你使得lamba_functor成为一个全局变量。
In that case, you could declare a function that invokes it: 在这种情况下,您可以声明一个调用它的函数:
void uglyWorkaround() {
globalLambdaFunctor();
}
and set pFunc
to uglyWorkaround()
. 并将
pFunc
设置为uglyWorkaround()
。
EDIT 编辑
Just a sidenote: if you are binding static text to the function call, you may completely omit bind()
call and write just: 只是一个旁注:如果你将静态文本绑定到函数调用,你可以完全省略
bind()
调用并只写:
void wrapper() {
func(TEXT("console.write('test')"));
}
and set pFunc
to wrapper()
. 并将
pFunc
设置为wrapper()
。
Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer?
绑定返回lambda_functor而不是函数指针,那么如何将此函子转换为函数指针?
I don't think you can. 我认为你不能。 However, off the top of my head, I can think of several alternatives:
然而,在我的头脑中,我可以想到几个选择:
Use boost::function<void()>
(or std::function()
if your compiler supports TR1 or C++11) instead of void (*)()
. 如果编译器支持TR1或C ++ 11,则使用
boost::function<void()>
(或std::function()
)而不是void (*)()
。
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. 将整个代码放入模板中,使
PFUNCPLUGINCMD
成为模板参数,并让函数模板参数推导出确切的类型。 That's a variation on the former, actually, where you would use the result of bind()
directly instead of having boost::function
abstract away the gory details. 这是前者的变体,实际上,你可以直接使用
bind()
的结果,而不是让boost::function
抽象出血淋淋的细节。
Create a wrapper that calls the functor returned by boost::bind()
. 创建一个调用
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 of
bind()
as a template argument, but need to have give the function access to it nevertheless, you will need a global variable for this. 但是,由于你不能使用
bind()
的结果作为模板参数,但是需要让函数访问它,你需要一个全局变量。 (The ability to avoid this is one of the main advantages of function objects, a very versatile of which is std::function
.) (避免这种情况的能力是函数对象的主要优点之一,其中一个非常通用的是
std::function
。)
Extend your PFUNCPLUGINCMD
callback type to support a user-provided parameter. 扩展
PFUNCPLUGINCMD
回调类型以支持用户提供的参数。 For C callbacks, this usually is a void*
. 对于C回调,这通常是一个
void*
。 However, if you pass the address of the object returned by bind()
to your callback, you would need to convert it into a pointer to the correct type - which, AFAIK, depends on the arguments provided to bind()
. 但是,如果将
bind()
返回的对象的地址传递给回调,则需要将其转换为指向正确类型的指针--AFAIK取决于为bind()
提供的参数。 In order to avoid that, you'd need to pass something that abstracts away the exact type. 为了避免这种情况,你需要传递抽象出确切类型的东西。 Again,
std::function
comes to the rescue. 再次,
std::function
来救援。
The first idea would be the best, but it requires you to be able to change PFUNCPLUGINCMD
. 第一个想法是最好的,但它要求你能够改变
PFUNCPLUGINCMD
。 The last one might be best when PFUNCPLUGINCMD
needs to be compatible with C, as it uses the common C callback idiom. 当
PFUNCPLUGINCMD
需要与C兼容时,最后一个可能是最好的,因为它使用常见的C回调习惯用法。
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
. 或者,如果您控制接收代码,那么您可以使用
boost::function<>
, 它将接受各种函数类型,包括指针和函数对象,如boost::bind
生成的函数对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.