2017-08-01 34 views
1

阅读定义C++函数在C中的结构

  1. possible to define a function inside a C structure? [duplicate]
  2. Define functions in structs

不知下面的解决方法是可行的,哪些可以在编译器级的最深影响后。

// 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遗留代码,但我的感觉是,在某些方面,我现在做两份不同类型。

+1

你也在使用两种不同的语言......你想达到什么目的? –

+1

如果使用C编译器进行编译,则在结构中没有C++函数。如果使用C++编译器编译,则没有C结构。是的,你有两种完全不同的类型。 – Gerhardh

+0

环境是一个自己的C++ 11库,它依赖于旧的C89库在其他库中。我的一些c文件是这个lib的客户端,并且是C11编译的;该示例结构将主要在我的库上共享,并且我想确保它是*完全相同的类型。 –

回答

4

看从你的问题这struct定义:

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

这是可能导致相同的内存中表示,当使用C和C++编译器针对同一平台编译。但你应该从来没有依靠这个。 C++编译器看到的类型比C编译器看到的类型多一个成员,因此它们基本上是不同的类型。因此,将它们视为未定义的行为。如果按照您的预期工作,则可以通过纯运气,并可能随时中断。

如已经评论的,引入virtual功能几乎可以保证打破它,如C++编译器将需要存储的vtable某处struct。但即使没有,也有很多其他方式可能会中断,例如编译器会添加不同的填充。只是不要这样做。

你可以做的反而是用普通的Çstruct用C添加包装类 ++当你需要它。

3

这两个是不同的类型。作为C编译的结果与编译为C++的类型不同。在同一个程序中同时使用两者(即将C和C++对象链接成一个exectuable),并且由于违反C++中的单一定义规则,结果将是未定义的行为。

这不是保持C和C++之间可移植性的方法。行为是不确定的,所以你可能会很幸运,并发现它的工作原理就像你打算的那样。但是,同样,这种行为是不确定的,所以它可能无法正常工作。

2

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

你想定义一个类型,是-afoo并且可以传递给库函数。因此,继承:

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 
}