C++ Using Class Method as a Function Pointer Type
在C库中,有一个函数在等待函数指针,以便:
1 | lasvm_kcache_t* lasvm_kcache_create(lasvm_kernel_t kernelfunc, void *closure) |
其中lasvm_kernel_t定义为:
1 | typedef double (*lasvm_kernel_t)(int i, int j, void* closure); |
现在,如果我将类中定义的方法发送到lasvm kcache-create:
1 2 3 | double cls_lasvm::kernel(int i, int j, void *kparam) ... lasvm_kcache_t *kcache=lasvm_kcache_create(&kernel, NULL); |
我得到:"无法将'double(cls_lasvm::)(int,int,void)'转换为'double()(int,int,void)'"
我该怎么办?
我假设
您可以使用该cookie向您正在处理的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | extern"C" double lasvm_kcache_create_callback( int i, int j, void* closure) { // have to get a cls_lasvm pointer somehow, maybe the // void* clpsure is a context value that can hold the // this pointer - I don't know cls_lasvm* me = reinterpret_cast<cls_lasvm*>( closure); return me->kernel( i, j) } class cls_lasvm //... { ... // the callback that's in the class doens't need kparam double cls_lasvm::kernel(int i, int j); }; ... // called like so, assuming it's being called from a cls_lasvm // member function lasvm_kcache_t *kcache=lasvm_kcache_create(&lasvm_kcache_create_callback, this); |
如果我错误地认为闭包是上下文cookie,那么
1 2 3 4 5 6 7 8 9 10 11 12 | extern"C" double lasvm_kcache_create_callback( int i, int j, void* closure) { // if there is no context provided (or needed) then // all you need is a static function in cls_lasvm return cls_lasvm::kernel( i, j, closure); } // the callback that's in the class needs to be static static double cls_lasvm::kernel(int i, int j, void* closure); |
注意C++中实现的C回调函数必须是EDOCX1×11。它可能在类中作为静态函数工作,因为类静态函数通常使用与C函数相同的调用约定。但是,这样做是一个等待发生的错误(见下面的注释),所以请不要使用
如果
如果它是一个不能修改代码的外部C库,那么就没有什么可以做的了。您将无法调用成员函数,因为它们需要
1 2 3 4 5 6 7 8 9 | typedef double (cls_lasvm::*lasvm_kernel_t_member)(int i, int j, void* closure); struct MyParam { A* pThis; lasvm_kernel_t_member pMemFun; void* kParam; }; |
我还没有编译它,希望它有意义。
然后在类中定义一个从库接收调用的静态方法:
1 2 3 4 5 6 7 8 | class cls_lasvm { static double test(int i, int j, void *kparam) { MyParam* pParam = reinterpret_cast<MyParam*>(kparam); return (pParam->*pMemFun)(i,j,pParam->kParam); } }; |
打电话时,您应使用以下内容:
1 2 3 4 5 6 7 | cls_lasvm a; MyParam param; param.pThis = &a; param.pMemFun = &cls_lasvm::kernel; param.kParam = NULL; lasvm_kcache_create(&cls_lasvm::test,&a); |
每个C++成员函数都有一个隐式的、隐藏的、第一个参数EDCOX1(0)。
因此,方法
要取得进展,请将方法转换为静态成员方法。这将删除