gpt4 book ai didi

c++ - 对象和 void 指针在 extern C 声明中是否可以交换?

转载 作者:搜寻专家 更新时间:2023-10-31 01:28:49 25 4
gpt4 key购买 nike

我有一些动态加载代码的外部“C”接口(interface)。对于该代码,一些对象是不透明的句柄,表示为 void*。界面如下所示:

extern "C" {
void* get_foo() { Foo* foo = /* create and remember object */; return foo; }
int foo_get_bar(void* Foo) { return ((Foo*)foo)->bar(); }
}

这种模式几乎是通过 C-API AFAIK 与 C++ 对象交互的标准方式。但是我想知道我是否可以省略那个指针转换?

代码的调用者是生成的,并且只链接到上面的接口(interface)(它有自己的函数声明)。所以它有效地生成了这样的代码:

void foo_get_bar(void*);
void* get_foo();

int do_something() { return foo_get_bar(get_foo()) };

我们可以假设调用者正确使用了代码(即,它没有传递错误的指针)。但当然它没有 Foo 指针的概念。

现在我可以将界面更改为(更简单的)变体吗:

extern "C" {
int foo_get_bar(Foo* Foo) { return foo->bar(); }
}

或者 void*Foo* 在链接器级别之间是否存在细微差别(例如,大小可能不匹配? ).

编辑:我可能对 C 中的调用者代码造成了一些混淆。没有 C 代码。没有 C 编译器,因此不涉及 C 类型检查器。生成调用方代码并使用 C-API。因此,要使用不透明结构,我需要知道 C-API 在编译后如何表示该指针。

最佳答案

我发现这个问题有点令人困惑,但如果我理解正确的话,这很好。在任何现代平台上,指向任何对象的指针的大小都是相同的(谢天谢地,我们已经摆脱了 __near__far__middling)。

所以我可能会在声明 get_foo() 的头文件中引入一些类型安全的概念:

// Foo.h
struct Foo;

extern "C"
{
Foo* get_foo ();
int foo_get_bar (Foo* Foo);
}

Foo 类(大概是 C++)的实现中,我们可能有:

// foo.cpp
struct Foo
{
int get_bar () { return 42; }
};

Foo* get_foo () { return new Foo (); }
int foo_get_bar (Foo *foo) { return foo->get_bar (); }

偷偷摸摸,但合法。您只需在 foo.cpp 中将 Foo 声明为 struct 而不是 class,这意味着如果您想要 private protected 您必须明确说明。

如果这不合胃口,那么您可以在 foo.h 中这样做:

#ifdef __cplusplus
class Foo;
#else
struct Foo;
#endif

然后在 foo.c 中将 Foo 声明为 class 而不是 struct。选择你的毒药。

Live demo .

关于c++ - 对象和 void 指针在 extern C 声明中是否可以交换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51204840/

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