简体   繁体   English

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

[英]Define a Forward-defined C++ struct by aliasing

I want to write a C-wrapper around an existing C++ codebase. 我想围绕现有的C ++代码库编写一个C包装器。 So I need to implement some C-API functions that merely forward their operations to the corresponding C++ methods. 所以我需要实现一些C-API函数,只是将它们的操作转发到相应的C ++方法。

My problem is, I cannot figure out how to implement a forward-defined struct by means of an existing class: 我的问题是,我无法弄清楚如何通过现有的类实现前向定义的结构:

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

In this situation, the C-API can and shall only work with pointers to myLib::Foo , which obviously works well, if I define myLib_foo as a new struct inside foo.cpp. 在这种情况下,如果我将myLib_foo定义为myLib_foo中的新结构,那么C-API可以并且只能使用指向myLib::Foo指针,这显然效果很好。 I guess it also works, if I define a struct myLib_foo somewhere else. 我猜它也有效,如果我在其他地方定义一个struct myLib_foo Yet, since I want to keep my namespaces manageable, I am searching a way to define myLib_foo to be equivalent to some existing (and completely defined) struct. 然而,由于我想保持我的命名空间可管理,我正在寻找一种方法来定义myLib_foo 等同于一些现有(和完全定义)的结构。 This, however does not work, since my compiler refuses the code above with "typedef redefinition with different types". 但这不起作用,因为我的编译器拒绝上面的代码“使用不同类型的typedef重定义”。 Apparently, it distinguishes between type-aliases and structs. 显然,它区分了类型别名和结构。

Is there even a way to achieve what I want or does C++ have no means for real type-aliases? 有没有办法实现我想要的东西,或者C ++无法实现真正​​的类型别名?

edit: By the answer below, I figured I can use inheritance plus static_cast: 编辑:通过下面的答案,我想我可以使用继承加上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()); }
}

The C code does not ever need a definition of the struct myLib_foo that it sees. C代码不需要它看到的struct myLib_foo的定义。

It handles it only through pointers and functions. 它只通过指针和函数来处理它。

On the C++ side a simple implementation is a struct containing a pointer to the "real" object that it represents. 在C ++方面,一个简单的实现是一个包含指向它所代表的“真实”对象的指针的struct You then define it in the ordinary way (in the C++ code), but of course with the name already established for the C code usage. 然后以普通方式(在C ++代码中)定义它,但当然已经为C代码使用建立了名称。

If you want to avoid even that little inefficiency, to hand out real object pointers to the C code, well then you have essentially two options: 如果你想避免那种效率低下的问题,那么将实际的对象指针分发给C代码,那么你基本上有两个选择:

  • reinterpret_cast , or reinterpret_cast ,或

  • static_cast with the not-quite-C struct as a (possibly empty) base class. static_cast使用not-quite-C结构作为(可能为空)基类。

But I would go for the simple implementation of myLib_foo as a struct with a pointer to the real one. 但我会将myLib_foo的简单实现作为一个带有指向真实指针的struct The KISS principle: Keep It Simple, Stupid * . KISS原则:保持简单,愚蠢* On second thoughts , to avoid allocation and deallocation issues, and to also avoid a formal dependency on the compiler (even if that would just be academic, a formality), I would go for the static_cast . 第二个想法是 ,为了避免分配和释放问题,并且还避免对编译器的正式依赖(即使这只是学术性的,形式化),我会选择static_cast For thinking about what it all entails, this seems simplest. 考虑到这一切需要什么,这似乎是最简单的。


*: Oh, the last few times I mentioned this principle on SO, those answers were heavily downvoted. *:哦,最近几次我在SO上提到了这个原则,那些答案都被严重低估了。 That has also happened when I have (correctly) proposed macros as solutions. 当我(正确地)提出宏作为解决方案时,也会发生这种情况。 I think one should be technically honest and ignore the general SO readership, so I mention it anyway. 我认为一个人应该在技术上诚实并且忽略一般的SO读者,所以无论如何我都提到它。

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

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