这是早期问题的完全重写版本; 我认为第一个版本省略了重要的细节; 这个提供了所有的背景.
我有一些C++ API的标题.API声明了一些这样的类:
class Foo
{
public:
inline void Bar(void);
/* more inlines */
private:
inline Foo();
/* maybe more inline constructors */
}
Run Code Online (Sandbox Code Playgroud)
即没有成员,除了构造函数之外,所有函数都是内联的和公共的.构造函数是私有的,因此,据我所知,C++,我无法真正称它们为.要创建这些对象,我应该使用auto_ptrs:
class FooAutoPtr : public std::auto_ptr<Foo>
{
public:
inline FooAutoPtr();
/* one for each Foo constructors */
}
Run Code Online (Sandbox Code Playgroud)
API还有第二组函数,如下所示:
void Foo_Bar(void *self);
Foo* Foo_Constructor();
Run Code Online (Sandbox Code Playgroud)
我们称它们为核心函数,因为它们是实际从主机应用程序导出的符号.不是C++类.
核心函数具有C链接(即它们声明为extern "C"),但它们被声明为获取和返回C++类型(例如,它们可以引用:)Foo &foo.最后,头部包含C++类的内联函数的实现.所有这些功能都是一样的:它们调用核心功能.例如,FooAutoPtr构造函数是这样的:
inline FooAutoPtr::FooAutoPtr()
{
reset(Foo_Constructor());
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,代码接收一些对象,该对象应该是Foo来自主机应用程序的指针,并将auto_ptrGizmo 更改为指向此对象.但对于开发人员来说,它看起来好像是一个真正的指针Foo.呼叫Foo::Bar()是这样的:
inline Foo::Bar()
{
Foo_Bar(this);
}
Run Code Online (Sandbox Code Playgroud)
这适用于所有C++类和方法.聪明,是吗?
现在,有人可以解释这一切意味着什么?:)它不是真正的C++ API,是吗?对我来说,它看起来更像是一个基于C API的瘦C++包装器.如果是这样,我可以重新声明核心函数以丢失C++位吗?我理解如何围绕C++编写一个C包装器(实际上,我已经编写过了),但是,如果可能的话,我宁愿丢失包装器并直接使用这些函数.但是我怎么会丢失C++的东西?
例如,可能有一个带引用的函数:
Bar& Foo_GetBar(void* self, const Baz& baz, int& i);
Run Code Online (Sandbox Code Playgroud)
现在我从我的C++包装器中调用它,如下所示:
typedef struct bar bar_t; /* and others */
/*...*/
bar_t*
foo_get_bar(foo_t* foo, baz_t* baz, int* i)
{
return (bar_t*) &Foo_GetBar(foo, *(Baz*)baz, *i);
}
Run Code Online (Sandbox Code Playgroud)
它工作(我不知道,如何).但我宁愿让它像这样重新宣布:
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
Run Code Online (Sandbox Code Playgroud)
更新:我发现一个有趣的事情证实了尼尔的答案.Common Lisp中的代码使用相同的API.(当然,它必须使用C部分.)而且,从我可以(几乎没有)在源代码中读取,作者只是使用指针代替引用.这是代码片段,它将C++声明转换为Lisp:
;; use * instead of & - we're not interested in C++ details
line (regex-replace-all "&" line "*")
Run Code Online (Sandbox Code Playgroud)
所以就是这样:)谢谢大家!
理论上,编译器如何处理 C 链接声明中的引用的细节是未指定的实现细节。然而,许多编译器将其视为指针。因此,如果 C++ 库标头导入Bar& Foo_GetBar(void* self, const Baz& baz, int& i);,那么您可以尝试将其导入到 C 标头中,bar_t* Foo_GetBar(foo_t* self, const baz_t* baz, int* i);并且它可能会起作用。
| 归档时间: |
|
| 查看次数: |
278 次 |
| 最近记录: |