C ++使用类方法作为函数指针类型

编程入门 行业动态 更新时间:2024-10-28 12:22:39
本文介绍了C ++使用类方法作为函数指针类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在C库中,有一个函数等待函数指针,使得:

lasvm_kcache_t * lasvm_kcache_create(lasvm_kernel_t kernelfunc, void * closure)

其中lasvm_kernel_t定义为:

$ b b

typedef double(* lasvm_kernel_t)(int i,int j,void * closure);

现在,如果我将类中定义的方法发送到lasvm_kcache_create:

double cls_lasvm :: kernel(int i,int j,void * kparam) ... lasvm_kcache_t * kcache = lasvm_kcache_create & kernel,NULL);

我得到:can not convert'double(cls_lasvm :: )(int,int, void )

我应该怎么办? p>

解决方案

我假设 closure 为使用回调获取适当的上下文。这是一个acomon成语的回调函数,似乎是基于你提供的片段发生了什么(但我不知道肯定,因为我不知道任何关于 kcache_create )

您可以使用该cookie传递指向 cls_lasvm

code>这样处理的实例:

externC double lasvm_kcache_create_callback(int i,int j,void * closure) { //必须得到一个cls_lasvm指针,也许 // void * clpsure是一个上下文值 //这个指针 - 我不知道 cls_lasvm * me = reinterpret_cast< cls_lasvm *>(closure); return me-> kernel(i,j) } class cls_lasvm // ... { ... //类中的回调doens't需要kparam double cls_lasvm :: kernel(int i,int j) ; }; ... //这样调用,假设它是从cls_lasvm中调用 //成员函数 lasvm_kcache_t * kcache = lasvm_kcache_create(& lasvm_kcache_create_callback,this);

如果我错误的关闭是一个上下文cookie,那么你的回调函数在 cls_lasvm 类需要是静态的:

externC double lasvm_kcache_create_callback(int i,int j,void * closure) { //如果没有上下文提供(或需要)然后 //所有你需要的是一个静态函数在cls_lasvm return cls_lasvm :: kernel(i,j,closure); } //类中的回调需要是static static double cls_lasvm :: kernel(int i,int j,void * closure);请注意,在C ++ 中实现的C回调函数必须 <$ c $ $ c $ b $ c> externC。它可能似乎在类中作为静态函数工作,因为类静态函数通常使用与C函数相同的调用约定。但是,这是一个等待发生的错误(见下面的注释),所以请不要 - 通过 externC包装。

如果 closure 不是上下文cookie,并且由于某种原因 cls_lasvm :: kernel c $ c>不能是静态的,那么你需要提出一种方法,在某处存储这个指针,并在 lasvm_kcache_create_callback ()函数,类似于我在第一个例子中的方式,除了指针必须来自一些机制,你自己设计。请注意,这可能会使用 lasvm_kcache_create()不可重入和非线程安全。根据您的具体情况,这可能是或可能不是问题。

In a C lib, there is a function waiting a function pointer such that:

lasvm_kcache_t* lasvm_kcache_create(lasvm_kernel_t kernelfunc, void *closure)

where lasvm_kernel_t is defined as:

typedef double (*lasvm_kernel_t)(int i, int j, void* closure);

Now, if I send a method defined in a class to lasvm_kcache_create:

double cls_lasvm::kernel(int i, int j, void *kparam) ... lasvm_kcache_t *kcache=lasvm_kcache_create(&kernel, NULL);

I get: "cannot convert ‘double (cls_lasvm::)(int, int, void)’ to ‘double ()(int, int, void)’"

What should I do?

解决方案

I'm assuming that the closure argument is a context 'cookie' for the use of the callback to get appropriate context. This is a acomon idiom for callback functions, and seems to be what's going on based on the snippets you've provided (but I don't know for sure, as I don't know anything about kcache_create() except what you posted here).

You can use that cookie to pass a pointer to the cls_lasvm instance you're dealing with like so:

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);

If I'm wrong about closure being a context cookie, then your callback function in the cls_lasvm class needs to be static:

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);

Note that a C callback function implemented in C++ must be extern "C". It may seem to work as a static function in a class because class-static functions often use the same calling convention as a C function. However, doing that is a bug waiting to happen (see comments below), so please don't - go through an extern "C" wrapper instead.

If closure isn't a context cookie and for some reason cls_lasvm::kernel() can't be static then you need to come up with a way to stash a this pointer somewhere and retrieve that pointer in the lasvm_kcache_create_callback() function, similar to the way I did in my first example, except that pointer has to come dfrom some mechanism you devise yourself. Note that this will likely make using lasvm_kcache_create() non-reentrant and non-threadsafe. That may or may not be a problem depending on your specific circumstances.

更多推荐

C ++使用类方法作为函数指针类型

本文发布于:2023-07-30 00:48:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1245065.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   函数   类型   方法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!