2012-01-16 10 views
5

Tôi đang tạo DLL bằng Visual C++ Express và khi khai báo extern ValveInterfaces* VIFace bên trong Required.h, trình biên dịch cho tôi biết rằng ValveInterfaces không được xác định. (Tôi muốn để lộ VIFace cho bất kỳ tập tin bao gồm Required.h)từ khóa bên ngoài "thiếu loại thông số"

Dưới đây là cấu trúc của tác phẩm của tôi:

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 

Ảnh chụp màn hình của lỗi: http://i.imgur.com/lZBuB.png

+0

Bạn không nên sử dụng tên riêng cho các nhân viên bảo vệ. Mặc dù nó không phải là nguyên nhân của vấn đề cụ thể của bạn (đó là do sự bao gồm vòng tròn của 'ValveInterfaces.h' và' Required.h'), nó có thể gây ra [vấn đề tương tự] (http://stackoverflow.com/questions/3345159/ trong-c-whats-so-đặc biệt-về-di-h). –

Trả lời

4

Đó lỗi đầu tiên:

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

là một giveaway chết rằng loại ValveInterfaceskhông được xác định d tại điểm mà trước tiên bạn cố gắng sử dụng nó.

Điều này hầu như không thay đổi xảy ra vì loại ValveInterfaces không xác định. Đó là một chút khó khăn để kể từ khi bạn đã cắt ra swathes rất lớn của ValveInterfaces.h nhưng, ngay cả khi nó được xác định ở đó, nó có thể là một sự kết hợp kỳ lạ của #pragma once và misplacement rõ ràng của _REQUIRED_H bao gồm bảo vệ (họ thường là required.h) đang làm bạn đau buồn.

+0

Huh, đó là những gì tôi nghĩ, nhưng tại sao phải không? Tôi đã bao gồm các tập tin tiêu đề trước khi tôi tuyên bố nó như là một extern. –

+3

Tôi đã dán toàn bộ ValveInterfaces.h vào bên trong. Tôi nghĩ rằng vấn đề của tôi là ValveInterfaces.h là bao gồm Required.h, mà cũng bao gồm cả ValveInterfaces.h. –

+0

Bạn có thể đúng. Tôi sẽ thả 'pragma once' hoàn toàn và sử dụng nhiều bảo vệ di động hơn. Và loại bỏ các tham chiếu vòng tròn là tốt. – paxdiablo

1

Bạn đang sử dụng ValveInterface (số ít) nhưng khai báo ValveInterfaces (số nhiều).

+0

Rất tiếc, đã nhập sai địa chỉ ... Phải là ValveInterfaces, đã chỉnh sửa nó. Intellisense không phát hiện lỗi (?) –

3

Lưu ý rằng bao gồm hình tròn, như cách bạn có Required.hValveInterfaces.h, thường là một mùi mã. Nếu bạn phá vỡ tham chiếu vòng tròn, các vấn đề như thế này ít có khả năng xuất hiện.

Những gì bạn có thể thử và thực hiện là chuyển tiếp khai báo nhiều nhất có thể trong ValveInterfaces.h và giữ riêng tư. Nó không giống như ValveInterfaces cần mọi thứ từ Require.h vì vậy đừng bao gồm nó.

#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