关键字"extern"和"缺少类型说明符"的问题

5
我正在使用 Visual C++ Express 创建一个 DLL,在 Required.h 中声明extern ValveInterfaces* VIFace时,编译器告诉我 ValveInterfaces 未定义。(我想将VIFace暴露给包括Required.h在内的任何文件)
以下是我的文件结构:

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


你不应该使用保留名称作为包含保护。虽然这不是你特定问题的原因(那是由于ValveInterfaces.hRequired.h的循环包含引起的),但它可能会导致类似的问题 - Mike Seymour
3个回答

4

第一个错误:

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

“is a dead giveaway that the ValveInterfaces type has not been defined at the point where you first try to use it.”的意思是在第一次尝试使用ValveInterfaces类型时,代码中出现了错误提示。

这种情况几乎总是因为ValveInterfaces的类型未知。由于你切掉了ValveInterfaces.h的大部分内容,所以很难判断它是否被定义。即使在那里进行了定义,也可能是一种怪异的组合,如#pragma once_REQUIRED_H包含保护的错位(它们通常应该在required.h中),这会引起麻烦。


哦,这正是我所想的,但为什么不是呢?在声明它为extern之前,我已经包含了头文件。 - Richie Li
3
我会尽力为您进行翻译。以下是需要翻译的内容:我已经将整个 ValveInterfaces.h 文件粘贴在里面。我认为我的问题在于 ValveInterfaces.h 包含了 Required.h,而 Required.h 也包含了 ValveInterfaces.h。 - Richie Li
你可能是对的。我会完全删除 pragma once 并使用更便携的包含保护。同时也要消除循环引用。 - paxdiablo

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

1

你正在使用ValveInterface(单数),但声明了ValveInterfaces(复数)。


抱歉,我打错了...应该是ValveInterfaces,我已经修改了。Intellisense没有检测到错误吗? - Richie Li

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接