2009-06-29 61 views
7

有沒有一種簡單的方法直接從C使用C++對象?我想公開一些從C++類到C或FFI(外部函數接口)的類。 當然,我可以寫一個這樣的東西:來自C的C++代碼和對象?

class Foo{ 
.... 
}; 

void *make_foo(...){ 
Foo *ptr = new Foo(..) 

return static_cast<void *>(ptr); 
} 

.. 

int *foo_method1(void *fooptr, ...){ 
Foo *ptr = static_cast<Foo*>(fooptr); 
} 

但是還有一個更簡單的方法?

+0

請問這與Lisp有什麼關係? – Svante 2009-06-30 10:47:46

回答

8

這通常是最簡單的方法。

還請記住,您還需要在所有C「包裝器」方法上使用extern "C"

7

你幾乎在那裏。用extern "C"前綴獨立函數以關閉C++編譯器的name mangling

例如:

extern "C" void *make_foo(...){ 
    Foo *ptr = new Foo(..) 

    return static_cast<void *>(ptr); 
} 
1

有沒有真正做一個簡單的方法。您可以使用SWIG轉到另一種語言,其中使用的用戶定義類型不只是聚合數據,而是轉換爲C語言,您必須使用C的對象概念。

1

您可以使用Verrazano/Fetter爲C++代碼生成CFFI綁定。 但它需要GCC-XML,我不確定它的可移植性。

1

如果可能,那麼讓你的類從一個結構派生。然後,您可以使用指針這個結構的C代碼:

// C++ code 
extern "C" struct Cfoo {}; 
extern "C" struct Cbar {}; 

class foo : public Cfoo {}; 
class bar : public Cbar {}; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

這不是嚴格意義上的錯誤,但是GCC至少發出警告不同類型的指針之間轉換。

void foo (void) { 
    struct Cfoo * pf; 
    struct Cbar * pb; 
    pf = pb;  // gcc warns 
} 

如果你不能繼承,則使用了類似的想法,但具有的C結構存放指向C++對象,並再次只向前聲明結構的C API中:

// C++ code 
class foo {}; 
class bar {}; 

extern "C" struct Cfoo { foo * pFoo; }; 
extern "C" struct Cbar { bar * pBar; }; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

的這裏的缺點是Cfoo和Cbar對象的生命週期需要照顧。