gpt4 book ai didi

c++ - 如何指定指向参数数量未知的 C 函数的 C++ 指针?

转载 作者:行者123 更新时间:2023-12-03 22:59:40 25 4
gpt4 key购买 nike

我正在编写一个 C 库,我希望它可以从 C 和 C++ 中使用。在某一时刻,它应该从用户那里接收一个带有 0-3 个参数的回调,稍后将在某个指针处调用该回调。像这样(代码的拷贝也可以作为 GitHub Gist 获得):

// app_c.c
#include <stdio.h>
#include "lib.h"

double f0(void) {
return 123;
}

double f2(double a, double b) {
return a + b;
}

int main() {
cb_arity = 0;
cb_func = f0;
printf("%f\n", cb_call());

cb_arity = 2;
cb_func = f2;
printf("%f\n", cb_call());
}
我能够创建一个指向 C 函数的指针,该函数采用未知(但仍然固定)数量的参数,注意它是 void (*cb_func)() ,不是 void (*cb_func)(void) :
// lib.h
#ifndef LIB_H_
#define LIB_H_

#ifdef __cplusplus
extern "C" {
#endif

extern int cb_arity;
extern double (*cb_func)();
double cb_call(void);

#ifdef __cplusplus
}
#endif

#endif // LIB_H_
// lib.c
#include "lib.h"
#include <stdlib.h>

int cb_arity;
double (*cb_func)();

double cb_call(void) {
switch (cb_arity) {
case 0:
return cb_func();
case 1:
return cb_func(10.0);
case 2:
return cb_func(10.0, 20.0);
case 3:
return cb_func(10.0, 20.0, 30.0);
default:
abort();
}
}
它在我的机器和 Wandbox 上都成功编译并运行.据我了解,没有调用 UB。
现在我也想让它在 C++ 中工作。不幸的是,看起来我现在需要 reinterpret_cast因为 ()在 C++ 中表示“无参数”,而不是“未知数量的参数”:
// app_cpp.cpp
#include <stdio.h>
#include "lib.h"

int main() {
cb_arity = 0;
cb_func = []() { return 123.0; };
printf("%f\n", cb_call());

cb_arity = 2;
cb_func = reinterpret_cast<double(*)()>(static_cast<double(*)(double, double)>(
[](double a, double b) { return a + b; }
));
printf("%f\n", cb_call());
}
据我了解,这里也没有调用 UB:虽然我转换了函数指针 double(*)(double, double)double(*)(void)在 C++ 中,它被转换回 double(*)(double, double)在调用之前的 C 代码中。
有没有办法摆脱 C++ 代码中这些丑陋的强制转换?我试过指定 cb_func 的类型如 void(*)(...) ,但 C++ 仍然不会隐式转换 double(*)(double, double)到它。

最佳答案

您可以保留它,而不是从回调中删除参数的数量。

// lib.h
#ifndef LIB_H_
#define LIB_H_

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
int arity;
union {
void(*zero)(void);
void(*one)(double);
void(*two)(double, double);
void(*three)(double, double, double);
}
} cb_type;
extern cb_type cb;

double cb_call(void);

#ifdef __cplusplus
}
#endif

#endif // LIB_H_
// lib.c
#include "lib.h"
#include <stdlib.h>

cb_type cb;

double cb_call(void) {
switch (cb.arity) {
case 0:
return cb.zero();
case 1:
return cb.one(10.0);
case 2:
return cb.two(10.0, 20.0);
case 3:
return cb.three(10.0, 20.0, 30.0);
default:
abort();
}
}
如果你不暴露 cb ,你不能错配 arity 和 union 成员:
// lib.h
#ifndef LIB_H_
#define LIB_H_

#ifdef __cplusplus
extern "C" {
#endif

void register_zero(void(*)(void));
void register_one(void(*)(double));
void register_two(void(*)(double, double));
void register_three(void(*)(double, double, double));

double cb_call(void);

#ifdef __cplusplus
}
#endif

#endif // LIB_H_

关于c++ - 如何指定指向参数数量未知的 C 函数的 C++ 指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67044361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com