简体   繁体   English

回调方法无法访问成员变量或实例

[英]Callback method cannot access member variables or instance

I am writing for a simulation that uses an old 3D model file format (Carbon Graphics' GEO, if you're interested), and the way the OpenSceneGraph plugin for this model format updates its internal variables is by you registering a callback method for the model to call when it's time to update its values. 我正在编写使用旧3D模型文件格式(如果您有兴趣的话,Carbon Graphics的GEO)的模拟,并且该模型格式的OpenSceneGraph插件更新其内部变量的方式是通过为需要更新其值时调用的模型。 The callback has the simulation time, the variable name, and its current value. 回调具有模拟时间,变量名称及其当前值。 You are to return back the new value for that variable. 您将返回该变量的新值。

So, in my code, I set the callback as follows: 因此,在我的代码中,我将回调设置如下:

headerNode->setUserUpdate(&FlightDriver::updateGeoVariable);

The class headerNode belongs to has the following variable: headerNode所属的类具有以下变量:

double (* uvarupdate)(const double t, const double val, const std::string name);

Every interval, it will call uvarupdate which I have set to: 每个间隔,它将调用uvarupdate ,我将其设置为:

updateGeoVariable(const double time, const double val, const std::string name)
{
    return flightData->getValue(name);
}

for each variable inside the model, one at a time. 对于模型中的每个变量,一次一次。 I can't make the method or the flightData member static, as they need to be unique per instance. 我不能将方法或flightData成员设为静态,因为它们在每个实例中都必须是唯一的。

I have a hunch that this callback is possibly being called from C code, because when I break, it seems to have no knowledge that it is inside a class, and if I change the signature, the same three values get passed and shoehorned into whatever parameters are first. 我有一种预感,可能是从C代码调用此回调,因为当我中断时,它似乎不知道它在类中,并且如果更改签名,则会传递相同的三个值并将其塞入任何内容中参数是第一个。

However, I really need access to the members of the class, to avoid a really dirty kludge. 但是,我确实需要访问该类的成员,以避免产生肮脏的麻烦。 Since the class itself is what drives a model in the 3D world, having 2 or more of these means that I get callbacks that say: "234, pitch, 90" and I have no way of knowing which model's variable that data belongs to. 由于类本身是3D世界中驱动模型的因素,因此拥有2个或更多类意味着我将收到以下回调:“ 234,pitch,90”,并且我无法知道数据属于哪个模型变量。

I could possibly recompile the DLL (as it is an OSG plugin) to take additionally a pointer to that instance, or an id, or something, and return it in the callback, but I'd really like to avoid that if possible. 我可能可以重新编译DLL(因为它是OSG插件)以另外获取指向该实例或ID或其他内容的指针,并在回调中返回它,但我真的想避免这种情况。

I've read about thunking, but it looks like that and most other ideas require access to the code that creates the callback. 我已经读过关于重击的内容,但是看起来很像,其他大多数想法都需要访问创建回调的代码。 Any ideas? 有任何想法吗?

You need to pass a pointer to method, but the uvarupdate is pointer to function, these are different types. 您需要传递一个指向方法的指针,但是uvarupdate是指向函数的指针,它们是不同的类型。 Pointer to a method contains implicit pointer to this of an instance, it doesn't fit into function-pointer. 指向一个方法包含隐含指向this实例的,它不适合函数指针。 You need to pass this in some another way. 您需要以其他方式传递this

If you do not change signature of the callback, you have to calculate an instance ( this ) somehow. 如果不更改回调的签名,则必须以某种方式计算实例( this )。 If it can be determined from name parameter, well, it's easy. 如果可以通过name参数确定,那很容易。 Another way is to create a trampoline for each instance you have. 另一种方法是为每个实例创建一个蹦床。 If there are only few instances, you can write a separate trampoline function for each instance. 如果只有几个实例,则可以为每个实例编写一个单独的蹦床函数。 Creating trampolines dynamically (in run-time) is tricky and non-portable: in fact, you need to write some machine instructions into RAM so that they call your method with the correct this parameter. 动态(在运行时)创建蹦床是棘手且不可移植的:实际上,您需要向RAM中写入一些机器指令,以便它们使用正确的this参数来调用您的方法。 But that's also possible, that's what some libraries do (eg VCL in Delphi). 但这也是可能的,这就是某些库的功能(例如,Delphi中的VCL)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM