這是一個完全重寫的版本an earlier question;我認爲第一個版本省略了重要細節;這個提供了所有的上下文。C/C++ API難題
我有一些C++ API的頭文件。 API聲明幾個這樣的類:
class Foo
{
public:
inline void Bar(void);
/* more inlines */
private:
inline Foo();
/* maybe more inline constructors */
}
即,沒有成員,所有函數都是內聯和公共的,除了構造函數。構造函數是私有的,所以,據我瞭解C++,我不能真正地調用它們。要創建這些對象,我應該使用auto_ptr
s到他們:
class FooAutoPtr : public std::auto_ptr<Foo>
{
public:
inline FooAutoPtr();
/* one for each Foo constructors */
}
的API也有這樣的第二套操作:
void Foo_Bar(void *self);
Foo* Foo_Constructor();
讓我們稱他們爲核心功能,因爲這些是從主機應用程序實際導出的符號。不是C++類。核心函數具有C鏈接(即它們被聲明爲extern "C"
),但是它們被聲明爲接受和返回C++類型(例如,它們可以引用:Foo &foo
)。最後,頭文件包含了C++類的內聯函數的實現。所有這些功能都是一樣的:他們稱之爲核心功能。例如,FooAutoPtr
構造是這樣的:
inline FooAutoPtr::FooAutoPtr()
{
reset(Foo_Constructor());
}
據我所知,代碼從主機應用程序接收應該是一個指向某個對象,以Foo
和改變auto_ptr
Gizmo將指向這個對象。但對開發者來說,它看起來好像是一個指向Foo
的真實指針。並呼籲Foo::Bar()
是這樣的:
inline Foo::Bar()
{
Foo_Bar(this);
}
這同樣適用於所有的C++的類和方法。聰明吧?
現在有人能解釋一下這是什麼意思? :)它不是一個真正的C++ API,是嗎?對我來說,它看起來更像是一個C++封裝的C++封裝。如果是這樣,可以重新聲明核心函數丟失C++位?我知道如何編寫一個圍繞C++的C封裝(實際上,我已經寫過),但是,如果可能的話,我寧願丟失封裝並直接使用函數。但是,我如何失去C++的東西?
例如,有可能是參考文獻的功能:
Bar& Foo_GetBar(void* self, const Baz& baz, int& i);
現在我把它從我的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);
}
和它的工作(我不知道,怎麼樣)。但我寧願把它重新聲明是這樣的:
/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);
更新:我發現證實Neil's answer一件有趣的事情。 Common Lisp中的代碼使用相同的API。 (當然,它必須使用C部分。)而且,從我可以(幾乎)讀取的源代碼中,作者只是使用指針代替引用。以下是將C++聲明轉換爲Lisp的代碼片段:
;; use * instead of & - we're not interested in C++ details
line (regex-replace-all "&" line "*")
這就是它:)謝謝大家!
哇,這是一個問題,這是一個問題'_'和'C++'_legitimately_標記。一種罕見的外觀...... – ildjarn
如果核心函數返回C++類型(引用),那麼它是真正的實時C++ API(不是C API),但它不是面向對象的。 –
@SethCarnegie就這樣:)你看,頭部甚至在覈心函數附近有一條評論,說這些是「僅限C的環境」。那麼,另一個過時的評論:) –