通过别名定义前向定义的C ++结构

时间:2014-01-15 14:19:21

标签: c++ types struct

我想围绕现有的C ++代码库编写一个C包装器。所以我需要实现一些C-API函数,只是将它们的操作转发到相应的C ++方法。

我的问题是,我无法弄清楚如何通过现有类实现前向定义的结构:

//Foo.hpp
namespace myLib {
  struct Foo {
    //some meaningful C++ body
  };
}

//foo.h
//#ifdef __cplusplus etc. left out
extern "C" {
  struct myLib_foo;

  myLib_foo* mkfoo();

  //etc.
}

//foo.cpp
extern "C" {
  #include "Foo.hpp"
  #include "foo.h"

  typedef myLib_foo myLib::Foo;  //this does not work

  myLib_foo* mkfoo() { return new myLib::Foo(); }
}

在这种情况下,如果我将myLib::Foo定义为foo.cpp中的新结构,那么C-API可以并且只能使用指向myLib_foo的指针,这显然效果很好。如果我在其他地方定义struct myLib_foo,我想它也有效。然而,由于我想保持我的名称空间可管理,我正在寻找一种方法来将myLib_foo定义为等效到一些现有(和完全定义的)结构。但这不起作用,因为我的编译器拒绝上面的代码“使用不同类型的typedef重定义”。显然,它区分了类型别名和结构。

有没有办法实现我想要的,或者C ++无法实现真正​​的类型别名?

修改 通过下面的答案,我认为我可以使用继承加上static_cast:

//foo.cpp
extern "C" {
  #include "Foo.hpp"
  #include "foo.h"    

  struct myLib_foo : public myLib::Foo {};  //this does work

  myLib_foo* mkfoo() { return static_cast<myLib_foo*>(new myLib::Foo()); }
}

1 个答案:

答案 0 :(得分:2)

C代码不需要它所见的struct myLib_foo的定义。

它只通过指针和函数来处理它。

在C ++方面,一个简单的实现是struct,它包含指向它所代表的“真实”对象的指针。然后以普通方式(在C ++代码中)定义它,但当然已经为C代码使用建立了名称。

如果你想避免那种效率低下,将实际对象指针分发给C代码,那么你基本上有两个选择:

  • reinterpret_cast

  • static_cast将非完全C结构作为(可能为空)基类。

但我会将myLib_foo的简单实现作为struct,并指向真实的。{/ del> KISS原则:保持简单,愚蠢 * 。关于第二个想法,为了避免分配和解除分配问题,并且还避免对编译器的正式依赖(即使这只是学术性,形式性),我会选择{{1} }。为了考虑这一切需要什么,这似乎是最简单的。


*:哦,最后几次我在SO上提到了这个原则,那些答案被严重低估了。当我(正确地)提出宏作为解决方案时,也会发生这种情况。我认为一个人应该在技术上诚实而忽略了一般的SO读者群,所以无论如何我都会提到它。