2012-10-02 57 views
0

我一直在關注如何從C中調用C++對象的成員函數。據我所知,C代碼應該將類解釋爲一個具有相同名稱的結構,並且每當它想通過這個類的一個對象調用一個函數時,它應該使用一箇中間回調函數。標題是這樣的:使用C/C++混合頭文件在C中使用C++對象

// CInterface.h 
#ifdef __cplusplus 
... 

class CInterface 
{ 
public: 
    ... 

    void OnMessage(U8* bytes); // I want to call this function from C. 

private: 
    ... 
}; 
#else 
typedef 
    struct CInterface 
     CInterface; 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

#if defined(__STDC__) || defined(__cplusplus) 
    //extern void c_function(CInterface*); /* ANSI C prototypes (shouldn't be needed) */ 
    extern CInterface* cpp_callback_function(CInterface* self, unsigned char * bytes); 
#else 
    //extern void c_function();  /* K&R style (shouldn't be needed) */ 
    extern CInterface* cpp_callback_function(unsigned char * bytes); 
#endif 

#ifdef __cplusplus 
} 
#endif 

,現在無法正確的C代碼如下所示:// main.c中 的#include 「CInterface.h」

int main(int argc, char* argv[]) 
{ 
    void* ptr; 
    int *i = ptr; // Code that only compiles with a C compiler 
    CInterface cinterface; // This should declare a struct 
} 

的錯誤是:錯誤C2079:'cinterface'使用未定義的結構'CInterface'。

聽起來像頭被讀爲C++代碼,因爲結構沒有定義,但main.c是由C根據Visual Studio編譯(我也通過添加一些C特定的代碼進行雙重檢查)。但是,如果我添加了這樣的括號:

CInterface cinterface(); 

代碼編譯這是沒有意義的我,現在的回調函數是在實現的對象不應該在C.

工作第三個文件,CInterface.cpp,充當「中間」。

所以問題是我如何解決這個錯誤信息,或者如果我得到了整個方法錯誤。這是我第一次混合使用C/C++代碼,而且我對這兩種語言都比較陌生。

+2

'CInterface cinterface();'聲明的函數,而不是一個對象,在C和C++。 –

+3

您從未爲C定義'struct CInterface',因此它是一個不完整的類型,您只能使用指向'CInterface'的指針。 (請注意未聲明類型和未定義類型之間的區別。) –

+1

不完整類型正是他想要的。 C編譯器不會理解C++類定義,因此您在C中所做的所有操作都是前向聲明該類,獲取並保存指向其實例的指針,並通過extern「C」函數將該指針傳遞迴C++。因爲C編譯器不知道類的內部實現細節(vtable等),所以即使可以嘗試再做也不安全。 – dajames

回答

0

在您的示例中,CInterface僅針對C++定義。如果仔細看看鏈接的示例,您會注意到Fred課程也是如此。

從C中只能傳遞指向CInterface的指針,並且必須依靠C鏈接定義的C++函數來實際操縱CInterface實例。

否則,您可以定義一個struct作爲在C和C++之間傳遞數據的方法。只要確保從C++中使用時它的定義聲明爲extern "C"

#ifdef __cplusplus 
extern "C" { 
#endif 

struct CandCPlusPlus { 
// ... 
}; 

#ifdef __cplusplus 
} 
#endif 
+0

謝謝。只是爲了擴大我對C++的理解:如果我定義結構以包含一些我希望將數據傳遞到C++的數據,會發生什麼情況。 C++會看到結構指針作爲一個對象指針,我猜...它會神奇地將結構數據轉換爲對象成員字段? – Jake

+0

在C++中,結構是一個默認情況下具有公共成員的類。雖然C++允許結構具有靜態數據成員和成員函數,但只要它具有公共的非靜態數據成員,就可以直接在C++和C之間共享結構。 –