更新时间:2022-10-16 18:30:27
这是不可能的,至少与 handler_t
签名。
虽然您可以创建你的.cpp一个免费的功能来包装成员通话,您需要一个指向富
实例:
无效my_wrap(INT富,无效*吧){
美孚* some_foo_instance = ...;
some_foo_instance->处理器(富,吧);
}INT主(INT ARGC,字符** argv的){
set_handler(安培; my_wrap);
}
您需要一些无效*传递富
实例作为处理程序属性:
//头
无效的typedef(* handler_t)(INT富,无效*酒吧,无效* ARG1);
无效set_handler(handler_t小时,无效* ARG1);//默认地将Impl。
无效set_handler(handler_t小时,无效* ARG1){
handler_ = H;
handler_arg1_ = ARG1;
}// CPP
无效my_wrap(INT富,无效*酒吧,无效* ARG1){
美孚* some_foo_instance =的static_cast<富*>(ARG1);
some_foo_instance->处理器(富,吧);
}//主
INT主(INT ARGC,字符** argv的){
富some_concrete_instance;
set_handler(安培; my_wrap,与的static_cast LT;无效*>(安培; some_concrete_instance));
}
I have a C library function that expects a function pointer for callback, and I want to pass in a C++ member function. The C++ function modifies a member variable, so I can't use a static free function (as suggested in several similar posts). My attempt (shown below) fails with a compiler error.
This post comes closest to what I need:
Using a C++ class member function as a C callback function
How can I do this without static functions? Thanks!
test.h
#ifndef TEST_H_
#define TEST_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*handler_t)(int foo, void *bar);
void set_handler(handler_t h);
#ifdef __cplusplus
}
#endif
#endif
test.c
#include "test.h"
#include <stdlib.h>
static handler_t handler_ = NULL;
void set_handler(handler_t h) {
handler_ = h;
}
void handle_event(int foo, void *bar) {
if (handler_ != NULL) handler_(foo, bar);
}
test.cpp
#include "test.h"
#include <iostream>
using namespace std;
class Foo {
public:
Foo() : ctr_(0) {};
// handler needs to access non-static variable, so it can't be static
void handler(int foo, void *bar) { ++ctr_; }
private:
int ctr_;
};
int main(int argc, char **argv) {
// error: can't convert to "void (*)(int, void*)"
set_handler(&Foo::handler);
cout << "done" << endl;
return 0;
}
GCC barf
$ gcc test.cpp test.c
test.cpp: In function ‘int main(int, char**)’:
test.cpp:18: error: cannot convert ‘void (Foo::*)(int, void*)’ to ‘void (*)(int, void*)’ for argument ‘1’ to ‘void set_handler(void (*)(int, void*))’
It is not possible, at least with that handler_t
signature.
While you can create a free function on your .cpp to wrap the member call, you need a pointer to the Foo
instance:
void my_wrap(int foo, void* bar) {
Foo* some_foo_instance = ...;
some_foo_instance->handler(foo, bar);
}
int main(int argc, char **argv) {
set_handler(&my_wrap);
}
You need some void* to pass the Foo
instance as a handler attribute:
// Header
typedef void (*handler_t)(int foo, void *bar, void* arg1);
void set_handler(handler_t h, void* arg1);
// Impl.
void set_handler(handler_t h, void* arg1) {
handler_ = h;
handler_arg1_ = arg1;
}
// cpp
void my_wrap(int foo, void* bar, void* arg1) {
Foo* some_foo_instance = static_cast<Foo*>(arg1);
some_foo_instance->handler(foo, bar);
}
// main
int main(int argc, char **argv) {
Foo some_concrete_instance;
set_handler(&my_wrap, static_cast<void*>(&some_concrete_instance));
}