Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C/C++;API难题_C++_C_Reference - Fatal编程技术网

C++ C/C++;API难题

C++ C/C++;API难题,c++,c,reference,C++,C,Reference,这是一个完全重写的版本;我认为第一个版本遗漏了重要的细节;这一个提供了所有的上下文 我有一些C++ API的头。API声明了如下几个类: class Foo { public: inline void Bar(void); /* more inlines */ private: inline Foo(); /* maybe more inline constructors */ } void Foo_Bar(void *self); Foo* Foo_Const

这是一个完全重写的版本;我认为第一个版本遗漏了重要的细节;这一个提供了所有的上下文

我有一些C++ API的头。API声明了如下几个类:

class Foo
{
public:
    inline void Bar(void);
    /* more inlines */
private:
    inline Foo();
    /* maybe more inline constructors */
}
void Foo_Bar(void *self);
Foo* Foo_Constructor();
inline FooAutoPtr::FooAutoPtr()
{
   reset(Foo_Constructor());
}
inline Foo::Bar()
{
    Foo_Bar(this);
}
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);
}
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
也就是说,没有成员,所有函数都是内联的和公共的,构造函数除外。构造函数是私有的,因此,就我所理解的C++而言,我不能真正调用它们。要创建这些对象,我应该使用
auto_ptr
s来创建它们:

class FooAutoPtr : public std::auto_ptr<Foo> 
{
public:
    inline FooAutoPtr();
    /* one for each Foo constructors */
}
我们把它们称为核心函数,因为它们实际上是从主机应用程序导出的符号。不是C++类。

核心函数具有C链接(即它们声明为“代码>外部”C“< /代码>”),但它们被声明为获取和返回C++类型(例如,它们可以引用:<代码> Foo&Foo)。最后,头包含C++类的内联函数的实现。所有这些函数的作用都是一样的:它们调用核心函数。例如,

FooAutoPtr
构造函数如下所示:

class Foo
{
public:
    inline void Bar(void);
    /* more inlines */
private:
    inline Foo();
    /* maybe more inline constructors */
}
void Foo_Bar(void *self);
Foo* Foo_Constructor();
inline FooAutoPtr::FooAutoPtr()
{
   reset(Foo_Constructor());
}
inline Foo::Bar()
{
    Foo_Bar(this);
}
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);
}
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
据我所知,代码从主机应用程序接收到一些应该是指向
Foo
的指针的对象,并将
auto_ptr
gizmo更改为指向此对象。但对于开发人员来说,它似乎是指向
Foo
的真正指针。调用
Foo::Bar()
的过程如下:

class Foo
{
public:
    inline void Bar(void);
    /* more inlines */
private:
    inline Foo();
    /* maybe more inline constructors */
}
void Foo_Bar(void *self);
Foo* Foo_Constructor();
inline FooAutoPtr::FooAutoPtr()
{
   reset(Foo_Constructor());
}
inline Foo::Bar()
{
    Foo_Bar(this);
}
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);
}
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
<>这是所有C++类和方法的结果。聪明吧

现在,有人能解释一下这一切意味着什么吗?:)它不是真正的C++ API,是吗?对我来说,它看起来更像一个瘦的C++包装器之上的一个C API。如果是,<强>我能重新声明核心函数以失去C++位< /强>吗?我知道如何在C++上写一个C包装(实际上,我已经写过了),但是,如果可能的话,我宁愿丢失包装器,直接使用这些函数。但是我怎么会失去C++的东西呢?p> 例如,可能有一个带有引用的函数:

Bar& Foo_GetBar(void* self, const Baz& baz, int& i);
现在我从我的C++包装器中调用它:
class Foo
{
public:
    inline void Bar(void);
    /* more inlines */
private:
    inline Foo();
    /* maybe more inline constructors */
}
void Foo_Bar(void *self);
Foo* Foo_Constructor();
inline FooAutoPtr::FooAutoPtr()
{
   reset(Foo_Constructor());
}
inline Foo::Bar()
{
    Foo_Bar(this);
}
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);
}
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
它是有效的(我不知道,如何)。但我更希望它重新申报如下:

class Foo
{
public:
    inline void Bar(void);
    /* more inlines */
private:
    inline Foo();
    /* maybe more inline constructors */
}
void Foo_Bar(void *self);
Foo* Foo_Constructor();
inline FooAutoPtr::FooAutoPtr()
{
   reset(Foo_Constructor());
}
inline Foo::Bar()
{
    Foo_Bar(this);
}
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);
}
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
更新:我发现一件有趣的事情证实了这一点。公共Lisp中的代码使用相同的API。(当然,它必须使用C部分。)而且,从我在源代码中(勉强)读到的情况来看,作者只是使用指针代替引用。下面是代码的代码段,它将C++声明转换成LISP:

;; use * instead of & - we're not interested in C++ details
line (regex-replace-all "&" line "*")

就这样:)谢谢大家

理论上,编译器如何处理C链接声明中的引用的细节是一个未指定的实现细节。然而,许多编译器将其视为指针。因此,如果C++库头导入“代码> bar和FooGeGeBar(Valu**,const BAZ&BAZ,INT&I);
然后您可以尝试将其作为
bar\u t*Foo\u GetBar(Foo\u t*self,const baz\u t*baz,int*i)导入到您的C头中并且它可能会正常工作

#define & *    // convert references into pointers.
停下来。正确的。那里这是一个玩笑,而不是试图看看一个答案可以累积多少反对票


但是重写头文件以指针替换引用的方法肯定会奏效。因为这些都是C函数,所以不必担心名称的混乱,而且我还没有看到一个编译器不将引用实现为指针。(还有其他可能的方法吗?

哇,这个问题被合法地标记为
c
c++
。一个罕见的外观…如果核心函数返回C++类型(引用),那么它是一个真实的C++(不只是一个API),但它不是面向对象的。@ SethCARNGIGE,所以它是这样的:你看,这个头甚至在核心函数旁边有一个注释,说这是“只针对C环境”。另一个过时的注释:但是,你的函数<代码> FooGuGeBug[B/COD] >仍然是用C++编译器编译的,对吗?但它将其导出为“C”,并且所有类型也都是C,所以我可以从普通的C中调用它。我怀疑是这样的,但没有得到确认就不敢开始:)谢谢!顺便说一句,我更新了关于Lisp代码的帖子,我刚刚发现它使用了相同的API,是的,它只是使用指针:)所以你是对的。
#define
只对标识符有效,所以你不能这样做:)@Seth:的确如此。这也很好,真的。