将C++成员函数传递给 C 函数

Pass a C++ member function to a C function

本文关键字:函数 成员 C++      更新时间:2023-10-16

我们有一个接受C函数指针的结构:

int one(int x)
{
}
int two(int x)
{
}
struct Cstruct
{
int (*fn1)(int);
int (*fn2)(int);
};

现在我有一个C++类,它有以下方法:

class A
{
public:
int one(int x)
{
}
int two(int x)
{
}
int three(int x)
{
struct Cstruct cstr = {&this->one, &this->two};
}
};

尝试将类 A 方法地址初始化为 Cstruct 编译器实例时,是否给出了无效转换的错误?

如何将类成员函数地址分配给 Cstruct?

您无法执行此操作,因为指向非静态成员函数C++指针与非成员函数指针类型不兼容。这是因为成员函数需要一个额外的参数 - 需要调用成员函数的对象,它成为调用this指针。

如果将成员函数设置为静态,则代码将编译。但是,它不一定能实现您想要实现的目标,因为onetwo无法访问A的其他非静态成员。

将成员函数传递给 C 函数的一个技巧需要传递一个带有"注册"记录的附加void*指针,并让 C 代码将其传递回静态回调函数:

struct Cstruct
{
void *context; // Add this field
int (*fn1)(void*, int);
int (*fn2)(void*, int);
};
class A
{
public:
static int oneWrap(void* ptr, int x)
{
return static_cast<A*>(ptr)->one(x);
}
static int twoWrap(void* ptr, int x)
{
return static_cast<A*>(ptr)->two(x);
}
int one(int x)
{
}
int two(int x)
{
}
int three(int x)
{
struct Cstruct cstr = {this, &this->oneWrap, &this->twoWrap};
}
};

C 代码需要将context的值传递给fn1fn2

cs.fn1(cs.context, 123);
cs.fn2(cs.context, 456);