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

Callback method cannot access member variables or instance

本文关键字:变量 实例 成员 访问 方法 回调      更新时间:2023-10-16

我正在为一个使用旧的3D模型文件格式(如果你感兴趣的话,可以使用Carbon Graphics的GEO)的模拟而写,而这种模型格式的OpenSceneGraph插件更新其内部变量的方式是,注册一个回调方法,让模型在更新其值时调用。回调具有模拟时间、变量名称及其当前值。您要返回该变量的新值。

因此,在我的代码中,我将回调设置如下:

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

headerNode所属的类具有以下变量:

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

每隔一段时间,它就会调用uvarupdate,我已经将其设置为:

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

对于模型中的每个变量,每次一个。我不能使方法或flightData成员成为静态的,因为它们需要在每个实例中是唯一的。

我有一种预感,这个回调可能是从C代码中调用的,因为当我中断时,它似乎不知道它在一个类中,如果我更改签名,同样的三个值会被传递并硬塞进第一个参数中。

然而,我真的需要访问该类的成员,以避免出现真正肮脏的混乱。由于类本身是3D世界中驱动模型的因素,拥有2个或多个类意味着我会收到回复,说:"234,pitch,90",我无法知道数据属于哪个模型的变量。

我可能会重新编译DLL(因为它是一个OSG插件),以获取指向该实例的指针、id或其他东西,并在回调中返回,但如果可能的话,我真的希望避免这种情况。

我读过关于thunking的文章,但它看起来是这样的,大多数其他想法都需要访问创建回调的代码。有什么想法吗?

您需要传递一个指向方法的指针,但uvarupdate是指向函数的指针,这是不同的类型。指向方法的指针包含指向实例的this的隐式指针,它不适合函数指针。你需要以其他方式通过this

若不更改回调的签名,就必须以某种方式计算一个实例(this)。如果它可以从name参数中确定,那么就很容易了。另一种方法是为每个实例创建一个蹦床。如果只有几个实例,则可以为每个实例编写一个单独的蹦床函数。动态创建蹦床(在运行时)很棘手,而且不可移植:事实上,您需要将一些机器指令写入RAM,以便它们使用正确的this参数调用您的方法。但这也是可能的,有些库就是这么做的(例如Delphi中的VCL)。