通过3d派对库回调成员函数
我正在使用粒子模拟库.通过以下库函数将相互作用添加到粒子的方式:
I'm working with a particle simulation library. The way interactions are added to particles it through the following library function:
AddInteraction(ParticleSet particleSet, void(*interaction)(xyz* p, xyz* v))
我现在想将成员函数传递给 AddInteraction.我明白,如果不改变库函数,这是不可能做到的.改变图书馆是我想避免的,但如果变化很小,我可以给图书馆的作者发邮件,要求实施.
I now want to pass a member function to AddInteraction. I've understood that this is impossible to do without changing the library function. Changing the library is something I'd like to avoid, but if the change is small I can mail the author of the library and ask for it to be implemented.
我想写一个简单的例子来说明如何做到这一点.可能有不同的解决方案:
I want to write a simple example of how it can be done. Different solutions are possible:
Lambda 表达式.这些将是完美的,但是该库使用 CUDA 和 NVCC,它们尚不支持 Lamda 表达式.
Lambda expressions. These would be perfect, however the library uses CUDA and NVCC, which don't support Lamda expressions yet.
函子.我认为函子可以完成这项工作.但是,我还没有设法让他们按照我想要的方式工作.例如,我无法获得要工作的函子列表.这个问题在 http://www.tutok.sk/fastgl/callback.html 在参数化调用者下:
Functors. I thought functors could do the job. However, I haven't managed to get them working in the way I want. For example, I can't get a list of functors to work. This problem is described in http://www.tutok.sk/fastgl/callback.html under Parameterize the Caller:
' 如果一个组件有很多回调关系,将它们全部参数化很快就会变得不可行.考虑一个想要维护一个单击事件时要通知的被调用者的动态列表.由于被调用者类型内置于 Button 类类型中,因此该列表必须是同类的或无类型的.'
' If a component has many callback relationships it quickly becomes unworkable to parameterize them all. Consider a Button that wants to maintain a dynamic list of callees to be notified upon a click event. Since the callee type is built into the Button class type, this list must be either homogeneous or typeless.'
我不得不承认,我不明白该网站上写的所有内容,所以那里可能会有答案.
I have to admit that I don't understand everything that is written on that site, so there might be an answer there.
- 使用 3d 派对库.例如,http://www.tutok.sk/上描述的使用模板函子库的回调"fastgl/callback.html,或使用 Boost::Function.但是,这些可能需要对我正在使用的粒子库进行重大更改,对吗?
- Using a 3d party library. For example the 'Callbacks Using Template Functors Library' as described on http://www.tutok.sk/fastgl/callback.html, or using Boost::Function. However, these will probably require major changes to the particle library I'm working with, right?
有其他选择吗?或者有没有办法让上述解决方案之一起作用?
Are there any alternatives? Or is there a way to get one of the above solutions to work?
非常感谢!
感谢您的建议.他们有所帮助,但我看不出他们如何为我的问题提供完整的解决方案.具体来说,我正在努力让它发挥作用:
Thanks for your suggestions. They help, but I fail to see how they give a complete solution to my problem. Specifically, I'm trying to get this to work:
std::vector<void(*)(xyz*,xyz*)> interactionList;
void AddInteraction(void(*func)(xyz*,xyz*))
{
interactionList.push_back(func);
}
void Simulate()
{
for(size_t i = 0; i < interactionList.size(); i++)
{
interactionList[i](0,0); //Would normally be called for every particle
}
}
class Cell {
public:
void UpdateParticle(xyz* p, xyz* v);
Cell()
{
AddInteraction(this->UpdateParticle); //Does not work
}
};
int main()
{
Cell cell1;
Cell cell2;
for(int i = 0; i < 100; i++)
{
Simulate();
}
return 1;
}
推荐答案
通常,回调函数有一个 void * 参数,该参数允许客户端代码为它可能需要的任何其他信息提供占位符.
Typically, callback function have a void * argument that allows client code a placeholder for any other information it may require.
这样,客户端代码可以传入任何他们想要的东西,并在调用回调时将其重新转换回原始类型.注意,调用代码知道原始类型.
This way, the client code can pass in anything they want and recast it back to the original type when the callback is invoked. Note, the calling code knows the original type.
这种类型的接口只允许 C 代码工作,但如果需要,可以很容易地将其包装在 C++ 对象中.至少,图书馆作者应该提供这个.
This type of interface allows C only code to work but it's pretty easy to wrap this in a C++ object if needed. At the very least, the library author should provide this.
编辑以回答 OP 评论
下面我适当地修改了 Cell 类.
EDIT TO ANSWER OPs COMMENT
Below I've modified the Cell class appropriately.
class Cell
{
public:
static void UpdateParticle(void *stuff, xyz* p, xyz* v) // this has to be static as others have mentioned, note the additional void * argument
{
Cell * c = (Cell *) stuff;
// do work
}
Cell()
{
AddInteraction(this, UpdateParticle); // note this takes a two items, both of which have to be saved for future use by AddInteraction and utilized by Simulate
}
};
相关文章