简体   繁体   English

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

[英]Define C++ functions in C structs

After reading 看完之后

  1. possible to define a function inside a C structure? 可以在C结构中定义函数? [duplicate] [重复]
  2. Define functions in structs 在结构中定义函数

I wonder if the following workaround would work and what can be its deepest implications at compiler-level. 我想知道以下变通办法是否行得通,它在编译器级别的最深层含义是什么。

// 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);

In my view is a great trick to leverage "struct polymorphism", being able to keep portability with C legacy code, but I have the feeling that in some way I'm now working with two different types. 在我看来,利用“结构多态性”可以保持C旧版代码的可移植性是一个绝妙的技巧,但是我觉得我现在正在某种程度上使用两种不同的类型。

Looking at this struct definition from your question: 从您的问题看这个struct定义:

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

It is likely to result in the same memory representation when compiled with a C and a C++ compiler targeting the same platform. 使用针对同一平台的C和C ++编译器进行编译时, 可能会导致相同的内存表示形式。 But you should never rely on this. 但是,您永远不要依赖于此。 The type the C++ compiler sees has one member more than the type the C compiler sees, so they are fundamentally different types. C ++编译器看到的类型比C编译器看到的类型多一个成员,因此它们本质上是不同的类型。 Therefore, treating them as the same is undefined behavior . 因此,将它们视为相同是未定义的行为 If this works as you expect, it's by pure luck and might break at any time. 如果这如您所愿,那么很幸运,并且可能随时中断。

As already commented, introducing a virtual function is almost guaranteed to break it, as the C++ compiler will need to store the vtable somewhere in the struct . 如前所述,引入virtual函数几乎可以保证将其破坏,因为C ++编译器需要将vtable存储在struct某个位置。 But even without that, there are many other ways in which it could break, for example because the compilers will add different padding. 但是即使没有这些,它也可能有许多其他破坏方式,例如,因为编译器将添加不同的填充。 Just don't do this. 只是不要这样做。

What you could do instead is use a plain C struct and add a wrapper class in C++ when you need it. 相反,您可以使用普通的 C struct并在需要时在C ++中添加包装器类

The two are distinct types. 两者是不同的类型。 Compiling as C results in a different type than compiling as C++. 作为C进行编译所产生的类型不同于作为C ++进行编译所产生的类型。 Use both in the same program at the same time (ie linking the C and C++ objects together into one exectuable) and the result will be undefined behaviour, due to violation on the one-definition rule in C++. 同时在同一程序中使用这两个程序(即将C和C ++对象链接在一起成为一个可执行文件),由于违反了C ++中的一定义规则,因此结果将是不确定的行为。

This is not the way to keep portability between C and C++. 这不是保持C和C ++之间可移植性的方法。 The behaviour is undefined, so you might get lucky and find it works as you intend. 该行为是不确定的,因此您可能会很幸运并发现它可以按预期工作。 But, equally, the behaviour is undefined, so it may not work. 但是,同样,该行为是不确定的,因此它可能无法正常工作。

If you want to ensure compatibility with a C library, this isn't the way. 如果要确保与C库的兼容性,则不是这样。

You want to define a type that is-a foo and can be passed to the library functions. 要定义一个类型,它是-一个 foo ,可以传递给库函数。 So do just that, inherit: 做到这一点,继承:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM