2016-08-26 13 views
-1

私はVisual StudioのC++環境に慣れようとしていますが、自分で定義したい機能のセットに問題があります。 hと.cppファイル。Visual Studioとは別の.hと.cppファイルのセットです。

私のプロジェクトには、common.hと呼ばれるいくつかの一般的な変数と定義を含むファイルがあります。

これまでのところ、私は単純なmain.cppを持っており、これらの機能を分けてプロジェクトを少しきれいにしています。

.hファイルは、これまでのところ、次のようになります

#pragma once 

#include "common.h" 

void SDLInitGameData(); 
void SDLCleanUp(); 

私は維持したい上記の定義は、ヘッダだけでなく、いくつかのヘルパー関数に記載されている.Hへの.cpp「プライベート」それらの機能に私のmain.cppに内

私はこれまでのところ、これを持っている:

#include <iostream> 

#include "common.h" 
#include "SDLInitialize.h" 

int main() 
{ 
    SDLInitGameData(); 
    system("pause"); 
    SDLCleanUp(); 
    return 0; 
} 

void ReportError(const char* ccpErrorMessage, const TInitializationError xReturnStatus) 
{ 
    cerr << ccpErrorMessage << ": "; 

    if (xReturnStatus == SDL_TTF_INIT_ERROR_CODE) 
    { 
     cerr << TTF_GetError(); 
    } 
    else if (xReturnStatus == SDL_INITFRAMEFRATE_ERROR_CODE) 
    { 
     cerr << "Unable to initialize FPSManager Object."; 
    } 
    else 
    { 
     cerr << SDL_GetError(); 
    } 

    cerr << "\n"; 

    SDLCleanUp(); 
    exit(xReturnStatus); 
} 

私COMMON.Hは、これまでのようになります。

#pragma once 

#include "SDL.h" 
#include "SDL_ttf.h" 
#include "SDL2_gfxPrimitives.h" 
#include "SDL2_framerate.h" 

#include <stdint.h> 

#ifdef _WIN32 
#include "Windows.h" 
#endif 

//Program will not compile without this 
#ifdef main 
#undef main 
#endif /* main */ 

#define SCRN_TITLE "Title" 
#define SCRN_WIDTH 640 
#define SCRN_HEIGHT 480 

#define FPS_CAP 30 

struct TGameData 
{ 
    static SDL_Window* Window; 
    static SDL_Renderer* Renderer; 
    static FPSmanager* Manager; 
} gxGameData; 

SDL_Window* TGameData::Window = nullptr; 
SDL_Renderer* TGameData::Renderer = nullptr; 
FPSmanager* TGameData::Manager = nullptr; 

enum TInitializationError 
{ 
    SDL_INIT_ERROR_CODE = 1, 
    SDL_CREATEWINDOW_ERROR_CODE, 
    SDL_CREATERENDERER_ERROR_CODE, 
    SDL_INITFRAMEFRATE_ERROR_CODE, 
    SDL_TTF_INIT_ERROR_CODE 
}; 

void ReportError(const char* ccpErrorMessage, const TInitializationError xReturnStatus); 

私はLNK2005の一握りを取得しています。私の研究から、これは「1つの定義ルール」の問題です。私がこのようなコードをmakefileで行うときは、SDLInitialize.h/cppファイルをコンパイルしてmainとリンクするルールがあります。これはVisual Studioでは動作しないようです。

私が間違っていることは何ですか?あなたのCOMMON.Hで

+0

質問には直接関係しませんが、コードやプロジェクト設定のどこかで何か変なことをしない限り、 '#undef main'は必要ありません。 – dxiv

+0

それは奇妙なケースですが、明らかにSDLmain.libにはmain関数があります。あなたがそれを持っていなければ、リンカは痛むでしょう。それをundefすれば、うまくコンパイルできます。 – Zulukas

+1

これは珍しいことであり、ベストプラクティスではありません。とにかく、私は好奇心で 'SDLmain'を探しました。それはあなたがそれをやる方法ではありません。 [main FAQ](http://wiki.libsdl.org/FAQWindows#I_get_.22Undefined_reference_to_.27SDL_main.27.22 _...)で、あなたの 'main' *はプロトタイプ' int main(int argc、char * argv []) 'つまり' int main() 'だけではありません。 – dxiv

答えて

1

:このヘッダファイルは、リンク時に重複した定義が故に、グローバルスコープでこれらの変数を定義しようとしているが含ま

SDL_Window* TGameData::Window = nullptr; 
SDL_Renderer* TGameData::Renderer = nullptr; 
FPSmanager* TGameData::Manager = nullptr; 

すべての翻訳単位。

代わりに、これらのすべてをexternと宣言して、それらを翻訳単位の1つに定義する必要があります。

+0

ありがとう、それはまさにそれでした。これらのリンカーのエラーは、単に彼らが言うことを言っているのではなく、ちょっとしたものです。 :) – Zulukas

関連する問題