感兴趣的C头(some_external_library.h
)声明以下struct
,包含一个函数指针:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
void (*function_ptr)(void);
} fp_test;
/* ... */
#ifdef __cplusplus
}
#endif
当some_external_library.c
中发生一些有趣的事件时,会调用此函数指针。
我想在名为struct
的C ++ class
实例中设置指向此Foo
实例的指针,然后设置function_ptr
的值到Foo
实例的非静态函数的地址。换句话说,我希望我的C ++代码定义这个函数指针的作用。
例如,这是一个类声明(foo.h
):
class Foo {
public:
fp_test *fp_test_ptr;
void setup(void);
void breakdown(void);
void my_callback(void);
};
有三个函数:一个用于初始化值的setup
函数,一个用于释放任何指针或对象的breakdown
函数,以及一个简单的my_callback
函数,它接受并不返回任何参数。
这是类定义(foo.cpp
):
int main(int argc, char** argv) {
Foo some_foo;
some_foo.setup();
some_foo.breakdown();
return EXIT_SUCCESS;
}
void Foo::setup(void) {
fp_test_ptr = new fp_test;
fp_test_ptr->function_ptr = &Foo::my_callback;
}
void Foo::breakdown(void) {
delete fp_test_ptr;
}
void Foo::my_callback(void) {
std::fprintf(stderr, "Callback called...\n");
}
编译时,我收到以下错误:
foo.h:: error: assigning to 'void (*)()' from incompatible type 'void (Foo::*)()'
fp_test_ptr->function_ptr = &Foo::my_callback;
^------------------
我尝试转换此调用,但收到一条错误消息,指出我无法从void (Foo::*)()
类型转换为void (*)()
。
如何在C ++中设置非静态方法作为C库的函数指针?
我能够获得static
Foo::my_callback()
版本的some_foo
进行编译,但我不认为我可以使用静态方法来满足我的需求,因为我无法访问类实例{{1}}中的非全局成员的状态,仅为全局成员的值。
有没有办法用非静态函数做到这一点?
答案 0 :(得分:2)
通常的方法是有两个函数:一个是静态函数,一个是成员函数,并将对象实例作为参数传递
class Foo {
public:
fp_test *fp_test_ptr;
void setup();
void breakdown();
void my_callback();
static void _my_callback(void* self);
};
void Foo::_my_callback(void* self)
{
reinterpret_cast<Foo*>(self)->my_callback();
}
将函数指针的C签名更改为
void (*function_ptr)(void*)
调用它时,将对象实例作为参数传递。
修改强> 要从C调用,大概你需要知道它所引用的对象,所以不知何故,你需要一个将C ++实例传递给C的方法。
Foo* fu1 = new Foo();
Foo* fu2 = new Foo();
/* fu1 and fu2 need to be passed to the C program */
...
/* Setting up */
fp_test pointerTest;
pointerTest.function_ptr = Foo::_my_callback;
...
/* Calling */
pointerTest.function_ptr(fu1);
pointerTest.function_ptr(fu2);
答案 1 :(得分:0)
这是不可能的。每个非静态的c ++成员函数都有一个隐藏的&#34; this *&#34;参数。所以函数签名总是不同的。