在 C 结构中定义C++函数

Define C++ functions in C structs

本文关键字:C++ 函数 定义 结构      更新时间:2023-10-16

阅读后

  1. 可以在 C 结构中定义函数吗?[重复]
  2. 在结构中定义函数

我想知道以下解决方法是否有效,以及它在编译器级别最深的含义是什么。

// foo.h
typedef struct foo
{
int i;
#ifdef __cplusplus
foo(int _i) : i(_i) {};
#endif
} foo;
// bar.c
#include "foo.h"
foo bar;
bar.i = 1;
// bar.cpp
#include "foo.h"
foo bar(2);

在我看来,利用"结构多态性"是一个很好的技巧,能够保持 C 遗留代码的可移植性,但我感觉在某种程度上我现在正在使用两种不同的类型。

从你的问题中看这个struct定义:

typedef struct foo
{
int i;
#ifdef __cplusplus
foo(int _i) : i(_i) {};
#endif
} foo;

当使用面向同一平台的 C 和 C++ 编译器进行编译时,可能会导致相同的内存表示形式。但你永远不应该依赖这个。C++编译器看到的类型比 C 编译器看到的类型多一个成员,因此它们是根本不同的类型。因此,将它们视为相同是未定义的行为。如果这如您所料,那纯粹是运气,随时可能破裂。

如前所述,引入virtual函数几乎肯定会破坏它,因为C++编译器需要将vtable存储在struct中的某个位置。但即使没有它,还有许多其他方式可能会中断,例如因为编译器将添加不同的填充。只是不要这样做。

相反,您可以做的是使用Cstruct,并在需要时在 C++ 中添加包装

两者是不同的类型。 编译为 C 会产生与编译为 C++ 不同的类型。 同时在同一程序中使用两者(即将 C 和 C++ 对象链接成一个可执行对象(,结果将是未定义的行为,因为违反了 C++ 中的单定义规则。

这不是在 C 和 C++ 之间保持可移植性的方法。 该行为是未定义的,因此您可能会很幸运并发现它按预期工作。 但是,同样,行为是未定义的,因此它可能不起作用。

如果你想确保与C库的兼容性,这不是办法。

您希望定义一个类型,该类型是- 一个foo并且可以传递给库函数。所以这样做,继承:

class shiny_foo : foo {
// Member functions and anything that changes the object layout.
};
extern "C" void c_bar_func(foo *);
void cxx_bar_func(shiny_foo& obj) {
// do stuff
c_bar_func(&obj); // obj *is-a* foo as well, remember
}