0

I am really not understanding this.

Basically, I am trying to make, as a library, some classes to aid in handling some DirectX stuff so that I don't have to do it in other games. GameBase is a class I made. This dll project compiles as a dll and it compiles without issue.

I have another project that references this one, and I made a class called BlankGame, which extends GameBase. Whenever I build this executable project, I get the following linker errors.

error LNK2019: unresolved external symbol "public: virtual __thiscall GameBase::~GameBase(void)" (??1GameBase@@UAE@XZ) referenced in function "public: virtual __thiscall BlankGame::~BlankGame(void)" (??1BlankGame@@UAE@XZ)

error LNK2001: unresolved external symbol "public: virtual void __thiscall GameBase::UnloadContent(void)" (?UnloadContent@GameBase@@UAEXXZ)

error LNK2001: unresolved external symbol "public: virtual bool __thiscall GameBase::LoadContent(void)" (?LoadContent@GameBase@@UAE_NXZ)

I defined GameBase.h, BlankGame.cpp and BlankGame.h below.

Gamebase.h

#include "stdafx.h"
#pragma once

#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")

DLEX class GameBase
{
public:
    virtual ~GameBase() = 0;

    virtual bool LoadContent();
    virtual void UnloadContent();
    bool Initialize(HINSTANCE hInst, HWND winHandle, struct DXInitOptions options);
    void ShutDown();
    void BeginScene(float red, float green, float blue, float alpha);
    void EndScene();
    virtual void Render() = 0;
    virtual void Update() = 0;

    void GetProjectionMatrix(D3DXMATRIX&);
    void GetWorldMatrix(D3DXMATRIX&);
    void GetOrthoMatrix(D3DXMATRIX&);

    void GetVideoCardInfo(char*, int&);

    bool CompileD3DShader(wchar_t* filePath, char* entry, char* shaderModel, ID3DBlob** buffer);

protected:
    ID3D11Device* dev;
    ID3D11DeviceContext* devContext;
    IDXGISwapChain* swapChain;
    ID3D11RenderTargetView* backBufferTarget;
    ID3D11Texture2D* depthStencilBuffer;
    ID3D11DepthStencilState* depthStencilState;
    ID3D11DepthStencilView* depthStencilView;
    ID3D11RasterizerState* rasterState;

    D3DXMATRIX projectionMatrix;
    D3DXMATRIX worldMatrix;
    D3DXMATRIX orthoMatrix;

    bool vsyncEnabled;
    int vidMemory;
    char vidCardDesc[128];
};

BlankGame.h

#pragma once

#include <D3D11.h>
#include <D3Dx11.h>
#include <D3Dx10.h>
#include <D3Dcompiler.h>
#include <DxErr.h>
#include <xnamath.h>

#include <GameBase.h>

class BlankGame : public GameBase
{
public:
    BlankGame();
    ~BlankGame();

    bool LoadContent();
    void UnloadContent();
};

BlankGame.cpp

#include "BlankGame.h"


BlankGame::BlankGame()
{

}

BlankGame::~BlankGame()
{
}

bool BlankGame::LoadContent()
{
    return true;
}

void BlankGame::UnloadContent()
{

}

What am I doing wrong? The way I made GameBase works in other projects I made as I followed DirectX tutorials, the only difference being GameBase would be in the same project as the subclass extending it, instead of in a separate library.

EdChum
  • 376,765
  • 198
  • 813
  • 562
Nkosi Dean
  • 227
  • 8
  • 18
  • Clearly you are not linking to some needed library. Consult the classes you are working with and the name of the libraries involved. Add the corresponding switches to the compiler/linker. – felixgaal May 27 '12 at 22:35
  • But I think I am. In the property settings for the project, I have, in the additional libraries, included DXHelper.lib (The name of the project that has the GameBase class in it). I have the path to the library set as well. Additionally, I also tried adding #pragma comment (lib, "DXHelper.lib") to the top of the BlankGame.h file, but the same errors are still being thrown. – Nkosi Dean May 27 '12 at 23:01
  • I think the problem is in the fact that you are compiling a DLL over static libraries (the .lib files). I'm no expert in the field, sorry. – felixgaal May 27 '12 at 23:05
  • How is the DLEX macro defined ? – alexisdm May 27 '12 at 23:08
  • In stdafx.h, I defined it with #define DLEX __declspec(dllexport). Sorry, I forgot to mention that. Additionally, I thought the way you used a dll was linking to the lib file in the project settings, and then the actual built exe would automatically use the dll file, so long as it is in the same directory as the exe. At least that worked for me with something else before... – Nkosi Dean May 27 '12 at 23:16
  • I'm surprised you don't get an error about the pure virtual functions `Render` and `Update` not being overridden. – Some programmer dude May 28 '12 at 06:10
  • I managed to fix it. I actually got it before you replied Joachim, but what you said was part of the fix. In GameBase, I made LoadContent and UnloadContent both equal to 0 in their declaration. I added Render and Update to the BlankGame class, and added definitions for them. Fixing these silly mistakes made everything work. – Nkosi Dean May 28 '12 at 16:05

1 Answers1

0

You have to put something like this in a header, in the place where your DLEX is defined

#if defined(_WIN32)
#   if defined(MAKE_DLL)
#       if defined(EXPORT_API)
#           define DLEX __declspec(dllexport)
#       else
#           define DLEX __declspec(dllimport)
#       endif
#   else
#       define DLEX 
#   endif
#else
#   define DLEX
#endif

Then when you compile your library, set MAKE_DLL and EXPORT_API.
No need to change anything in your client.
This piece of preprocessor code will detect if it's compiling the library or linking against it using the EXPORT_API; if it's not defined it will import the functions but only if it's set to make a DLL (as opposed to static library).

Julien Lebot
  • 3,092
  • 20
  • 32