gpt4 book ai didi

c++ - C 接口(interface)是否关心指向的类型?

转载 作者:太空宇宙 更新时间:2023-11-04 16:01:12 25 4
gpt4 key购买 nike

我有两段代码:第一段在 C++ 程序中,是我从外部加载和调用函数的地方 test_lib.so :

typedef void *(*init_t)(); // init_t is ptr to fcn returning a void*
typedef void (*work_t)(void *); // work_t is ptr to fcn taking a void*

void *lib = dlopen("test_lib.so", RTLD_NOW);

init_t init_fcn = dlsym(lib, "test_fcn");
work_t work_fcn = dlsym(lib, "work_fcn");

void *data = init_fcn();
work_fcn(data);

第二段代码编译为test_lib.so。 :

struct Data {
// ...
};

extern "C" {
void *init_fcn() {
Data *data = new Data; // generate a new Data*...
return data; // ...and return it as void*
}

void work_fcn(void *data) { // take a void*...
static_cast<Data *>(data)->blabla(); // ...and treat it as Data*
static_cast<Data *>(data)->bleble();
}
}

现在,第一段代码不需要知道什么Data是,它只是传递指针,所以它是一个 void* .但是图书馆,它直接与 data 一起工作的方法和成员,需要知道,所以它必须转换 void* s 至 Data*

但是这两段代码之间的接口(interface)只是一些带有指针参数和/或返回类型的函数。我可以保留 void*在客户端中,更改 void* 的每个实例在图书馆给Data* .我这样做了,一切正常(我的系统是 Linux/GCC 6.2.1)。

我的问题是:我是幸运的,还是这保证在任何地方都有效?如果我没记错的话,调用一些 f(Data*) 的结果用void*参数就像称为 reinterpret_cast<Data*> 一样在 void* 上--- 那不可能是危险的。对吧?

编辑: 不,只是制作 Data对客户端代码透明的类型将不起作用。客户端代码通过相同的 API 调用许多库,但每个库可能有自己的实现。对于客户,Data可以是任何东西。

最佳答案

通过错误的函数类型调用任何函数自动成为未定义行为。来自 C++ 标准草案 n4604(大致为 C++17)[expr.reinterpret.cast]:

A function pointer can be explicitly converted to a function pointer of a different type. The effect of calling a function through a pointer to a function type that is not the same as the type used in the definition of the function is undefined. Except that converting a prvalue of type "pointer to T1" to the type "pointer to T2" (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

通过带有错误链接的函数指针类型调用任何函数也是未定义的行为。您的 typedef 不使用 "C" 链接,因此 UB。来自 n4604 草案 [expr.call] 部分:

Calling a function through an expression whose function type has a language linkage that is different from the language linkage of the function type of the called function’s definition is undefined.

除此之外,不同的指针类型不需要具有相同的表示。 (cv-qualified) void* 可以容纳任何对象指针,但其对齐限制与 char* 相同(即没有限制),因此,它是不一定表示与其他对象指针类型和 may not even be the same size 兼容. (毫无疑问,对象指针、函数指针和指向成员的指针的变体在现实世界的系统中通常大小不同。)

关于c++ - C 接口(interface)是否关心指向的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43774223/

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