5

I'm creating a DLL using Visual C++ Express, and when declaring extern ValveInterfaces* VIFace inside Required.h, the compiler is telling me that ValveInterfaces isn't defined. (I want to expose VIFace to any file including Required.h)

Here is the structure of my files:

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

Screenshot of errors: https://i.stack.imgur.com/1ZUph.png

Richie Li
  • 1,257
  • 2
  • 13
  • 20
  • You shouldn't use reserved names for include guards. Although it's not the cause of your particular problem (that's due to the circular inclusion of `ValveInterfaces.h` and `Required.h`), it can cause [similar problems](http://stackoverflow.com/questions/3345159/in-c-whats-so-special-about-move-h). – Mike Seymour Jan 16 '12 at 11:35

3 Answers3

4

That first error:

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.

This almost invariably occurs because the type of ValveInterfaces is unknown. It's a little hard to tell since you've cut out huge swathes of ValveInterfaces.h but, even if it's defined there, it could be a weird combination of #pragma once and the apparent misplacement of the _REQUIRED_H include guards (they would normally be in required.h) which is causing you grief.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Huh, that's what I thought, but why isn't it? I included the header file before I declare it as an extern. – Richie Li Jan 16 '12 at 07:52
  • 3
    I've pasted the entire ValveInterfaces.h inside. I think my problem is that ValveInterfaces.h is including Required.h, which is also including ValveInterfaces.h. – Richie Li Jan 16 '12 at 07:57
  • You may be right. I would drop the `pragma once` altogether and use the more portable include guards. And get rid of circular references as well. – paxdiablo Jan 16 '12 at 07:59
3

Note that circular inclusion, like how you have Required.h and ValveInterfaces.h, is usually a code smell. If you break up the circular reference, problems like these are less likely to come up.

What you can try and do is forward declare as much as you can in ValveInterfaces.h and keep it self-contained. It doesn't look like ValveInterfaces needs everything from Requires.h so don't include it.

#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
greatwolf
  • 20,287
  • 13
  • 71
  • 105
1

You're using ValveInterface (singular) but declaring ValveInterfaces (plural).

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Sorry, typed it in wrong... Should be ValveInterfaces, edited it. Intellisense doesn't detect the error (?) – Richie Li Jan 16 '12 at 07:50