问题描述
由于我的last最近的问题不幸的措辞,并导致解决另一个问题,然后我的,在这里我将尝试制定我的实际问题,以明确的方式。
在我们开始之前,作为一个旁注,我整合了JavaScript引擎V8到我的C ++应用程序。这就是在本例中所有类型从何而来。而这也是我需要在最后一个原函数指针的事实的原因。但我细说了下文。
从类中我需要通过一个Lambda前pression与捕获子句 [=]
作为类型参数 STD ::功能
给另一个函数,并将其转换为原始函数指针那里。
在此code, InvocationCallback
简直就是与签名功能的typedef 处理<价值>(参数常量和放大器;)
。
的typedef处理< VALUE> (* InvocationCallback)(参数常量和放大器;);无效绑定(字符串名称,功能和LT;处理< VALUE>(参数常量和放大器;)>功能)
{
InvocationCallback *功能= Function.target< InvocationCallback>();
}
所有的lambda前pressions具有相同的签名,太。需要注意的是处理<弦乐>
是兼容处理<价值>
在这个例子中。它是由JavaScript引擎V8给出了。
绑定(名,[=](常量参数和放大器;参数) - >处理< VALUE> {
手柄<串GT;结果=字符串::新(名称()c_str());
返回结果;
});
C ++允许我到这个拉姆达为的std ::功能
传递给函数的上方。但我想一个lambda前pression还存储参考对象是指。不知怎的,由指定的访问[=]
必须实现。这可能是铸造的原因的std ::功能
来的原始函数指针失败。
InvocationCallback *功能= Function.target< InvocationCallback>();
有既不是一个编译时错误,也不是一个运行时错误,但调试器告诉我,这导致空指针。但我需要做进一步处理原始函数指针。我想我可以在的std ::绑定
拉姆达转换ING引用或这个
终场第一。
更新:由于这似乎是不可能得到国家走出拉姆达的,这就是我试过了。它编译但函数
出来是一个空指针。
绑定(名,对此,[](基*的对象,常量参数和放大器;参数) - >处理< VALUE> {
返回V8 ::字符串::新(((*派生)对象) - 方式>名称()c_str());
});无效绑定(字符串名称,模块*对象,功能和LT;处理< VALUE>(模块*,参数常量和放大器;)>功能)
{
功能<&手柄LT; VALUE>(参数常量和放大器;)>方法=的std ::绑定(函数,对象的std ::占位符:: _ 1);
InvocationCallback *功能= method.target< InvocationCallback>();}
您不能,因为它可以捕获一个lambda是的闭合的,所以它有状态(它是与实例变量的对象)。一个函数指针没有状态。因此,你不能没有做到这一点无论1)您所使用的API需要的函数指针也可以让你通过,你传递状态的用户数据参数,或者2)存储在一个全局变量或东西的状态。
周围堆栈溢出搜索成员函数回调,你会得到一个想法(基本上,你是想用一个成员函数时,运算符()
,作为回调)。
Since my last recent question was unfortunately worded and resulted in a solution to another problem then mine, here I will try to formulate my actual problem in a clear way.
Before we start, as a sidenote, I am integrating the Javascript Engine V8 into my C++ application. That's where all the types in the example come from. And that's also the reason for the fact that I need a raw function pointer in the end. But I elaborate on this below.
From inside a class I need to pass a lambda expression with the capture clause [=]
as parameter of the type std::function
to another function and cast it to a raw function pointer there.
In this code, InvocationCallback
is simply a typedef for a function with the signature Handle<Value>(Arguments const &)
.
typedef Handle<Value> (*InvocationCallback)(Arguments const &);
void Bind(string Name, function<Handle<Value>(Arguments const &)> Function)
{
InvocationCallback* function = Function.target<InvocationCallback>();
}
All the lambda expressions have the same signature, too. Note that Handle<String>
is compatible to Handle<Value>
in this example. It's given by the Javascript Engine V8, too.
Bind("name", [=](const Arguments& args) -> Handle<Value>{
Handle<String> result = String::New(Name().c_str());
return result;
});
C++ allows me to pass this lambda as std::function
to the function above. But I guess a lambda expression also stores a reference to object it refers. Somehow the access specified by [=]
must be realized. That might be the reasons that casting the std::function
to a raw function pointer fails.
InvocationCallback* function = Function.target<InvocationCallback>();
There is neither a compile time error nor a runtime error but the debugger tells me that it results in a null pointer. But I need the raw function pointer for further processing. I guess I could convert the lambda after std::bind
ing the reference or this
-pointer first.
Update: Since it seems to be impossible to get the state out of the lambda, this is what I tried. It compiles but function
come out to be a null pointer.
Bind("name", this, [](Base* object, const Arguments& args) -> Handle<Value>{
return v8::String::New(((Derived*)object)->Name().c_str());
});
void Bind(string Name, Module *Object, function<Handle<Value>(Module*, Arguments const &)> Function)
{
function<Handle<Value>(Arguments const &)> method = std::bind(Function, Object, std::placeholders::_1);
InvocationCallback* function = method.target<InvocationCallback>();
}
You can't, because a lambda which captures is a closure, so it has state (it is an object with instance variables). A function pointer has no state. Thus, you cannot do this without either 1) the API you are using that requires the function pointer also allows you to pass a user data argument where you pass the state, or 2) storing the state in a global variable or something.
Search around Stack Overflow for "member function to callback" and you will get an idea (basically, you are wanting to use a member function, the operator()
, as a callback).
这篇关于拉姆达转换与存储在的std ::函数原始函数指针捕捉条款的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!