2012-01-16 113 views
5

我使用Visual C++ Express創建了一個DLL,並且在Required.h內聲明 extern ValveInterfaces* VIFace時,編譯器告訴我沒有定義ValveInterfaces。 (我要揭露VIFace到包括Required.h任何文件)extern關鍵字「缺少類型說明符」

這裏是我的文件結構:

DLLMain.cpp

#include "Required.h" //required header files, such as Windows.h and the SDK 

ValveInterfaces* VIFace; 

//the rest of the file 

Required.h

#pragma once 
//include Windows.h, and the SDK 
#include "ValveInterfaces.h" 

extern ValveInterfaces* VIFace; //this line errors 

ValveInterfaces.h

#pragma once 
#ifndef _VALVEINTERFACES_H_ 
#define _VALVEINTERFACES_H_ 
#include "Required.h" 

class ValveInterfaces 
{ 
public: 
    ValveInterfaces(void); 
    ~ValveInterfaces(void); 
    static CreateInterfaceFn CaptureFactory(char *pszFactoryModule); 
    static void* CaptureInterface(CreateInterfaceFn fn, char * pszInterfaceName); 
    //globals 
    IBaseClientDLL* gClient; 
    IVEngineClient* gEngine; 
}; 
#endif 

錯誤的截圖: http://i.imgur.com/lZBuB.png

+0

您不應該使用保留名稱作爲include guard。雖然它不是你的特定問題的原因(這是由於'ValveInterfaces.h'和'Required.h'的循環包含),它可能會導致[類似的問題](http://stackoverflow.com/questions/3345159/在-C-什麼那麼特殊之處的舉動-H)。 – 2012-01-16 11:35:39

回答

4

這第一個錯誤:

error C2143: syntax error : missing ';' before '*' 

是,ValveInterfaces類型有一個大破綻被定義d在你第一次嘗試使用它的地方。

這幾乎總是發生,因爲ValveInterfaces的類型未知。這是有點難以分辨,因爲你已經削減了大量的ValveInterfaces.h,但即使它在那裏定義,它可能是一個奇怪的組合#pragma once和明顯的錯位_REQUIRED_H包括警衛(他們通常會在required.h),其中正在引起你的悲傷。

+0

呵呵,這就是我的想法,但爲什麼不呢?我在將其聲明爲extern之前包含頭文件。 – 2012-01-16 07:52:09

+3

我粘貼了整個ValveInterfaces.h裏面。我認爲我的問題是ValveInterfaces.h包含Required.h,它也包含ValveInterfaces.h。 – 2012-01-16 07:57:18

+0

你可能是對的。我會一次性放棄'編譯指示',並使用更便攜的包含警衛。並且擺脫循環引用。 – paxdiablo 2012-01-16 07:59:42

1

您使用ValveInterface(單數),但聲明ValveInterfaces(複數)。

+0

對不起,輸入錯誤...應爲ValveInterfaces,編輯它。智能感知不會檢測到錯誤(?) – 2012-01-16 07:50:20

3

請注意,通常包含圓形包含,例如Required.hValveInterfaces.h,通常是代碼異味。如果你分解循環引用,像這樣的問題不太可能出現。

你可以嘗試做的事情是儘可能多地向前申報ValveInterfaces.h,並保持它自成一體。它看起來並不像ValveInterfaces需要Requires.h中的所有內容,所以不要包含它。

#ifndef VALVEINTERFACES_H 
#define VALVEINTERFACES_H 
// CreateInterfaceFn probably need to be fully defined 
// so just pull whatever header has that. Don't include 
// Required.h here, there's no need for it. 

class IBaseClientDLL; 
class IVEngineClient; 
class ValveInterfaces 
{ 
public: 
    ValveInterfaces(); 
    ~ValveInterfaces(); 
    static CreateInterfaceFn CaptureFactory(char *pszFactoryModule); 
    static void* CaptureInterface(CreateInterfaceFn fn, char * pszInterfaceName); 
    //globals 
    IBaseClientDLL* gClient; 
    IVEngineClient* gEngine; 
}; 

#endif