[英]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 The KISS principle: Keep It Simple, Stupid * . myLib_foo
as a struct
with a pointer to the real one. 但我会将
myLib_foo
的简单实现作为一个带有指向真实指针的struct
。 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.