ある比較的有名なゲームプログラミング(C++です)のエラーの話です。
点をいろいろとうつプログラムなんですが、
main.cpp
udate.cpp
Framework.h
DebugStream.h
がありまして
mainが
#include "Framework.h"
namespace GameLib{
void Framework::update(){
unsigned* vram = videoMemory();
static unsigned i;
vram[ i ] += i * 100;
i += 9973; //1万以下最大の素数
i %= ( width() * height() );
}
}
で
updateが
#include "Framework.h"
namespace GameLib{
void Framework::update(){
getInput();
updateGame();
draw();
}
}
ヘッダーにFrameworkとDebugStreamがあります。
プロパティのリンカで
追加のライブラリにD:\GameLib2008\2DGraphics1\lib
追加の依存ファイルにGameLib_d.lib
とインクルードディレクトリの設定を本に指示されたとおりにやりました。
しかし、ビルドすると
....\update.cpp(6) : error C3861: 'getInput': 識別子が見つかりませんでした
....\update.cpp(7) : error C3861: 'updateGame': 識別子が見つかりませんでした
....\update.cpp(8) : error C3861: 'draw': 識別子が見つかりませんでした
エラー3
というのがでます。
ヘッダーにエラーが出てないので、
自分はライブラリに設定したものが動いてないと勝手に思って
いろいろしているんですが全く解決できません。
私は知識はローベルのC++の本をひととおりやったくらいです。
ライブラリ(---.libなど)についてはほとんど知識がありません。
いきなりでずうずうしいかもしれませんが、本当に悩んでいます。
みなさんの意見がほしいです。
長い文章読んでいただきありがとうございます。
エラーで3週間ぐらい悩んでます。
Re:エラーで3週間ぐらい悩んでます。
どういう処理をしたいのか分からないのですけど、
Framework.h にある Framework クラスには getInput() と updateGame() と draw() は宣言されているのでしょうか。
できればヘッダファイルの中も貼り付けて下さい。
あと、main.cpp と update.cpp の両方で Framework::update() を定義しているので、リンク時に多重定義でエラーになりますね。
そこも修正する必要があると思います。
あと、そのエラーはコンパイルエラーなので、リンク時に発生するエラーとは関係ありません。
つまり *.lib はリンク時に使用するものなので無関係ということです。
Framework.h にある Framework クラスには getInput() と updateGame() と draw() は宣言されているのでしょうか。
できればヘッダファイルの中も貼り付けて下さい。
あと、main.cpp と update.cpp の両方で Framework::update() を定義しているので、リンク時に多重定義でエラーになりますね。
そこも修正する必要があると思います。
あと、そのエラーはコンパイルエラーなので、リンク時に発生するエラーとは関係ありません。
つまり *.lib はリンク時に使用するものなので無関係ということです。

Re:エラーで3週間ぐらい悩んでます。
ご返事ありがとうございます。
エラーがこの3つ以外出てないんですが二重定義は
ひっかかってるのでしょうか?
こちらがFrameworkです。
#ifndef INCLUDED_GAMELIB_FRAMEWORK_H
#define INCLUDED_GAMELIB_FRAMEWORK_H
namespace GameLib{
class Framework{
public:
Framework();
///ユーザ定義関数。これを書く。
void update();
///インスタンス取得
static Framework instance();
///画面幅取得
int width() const;
///画面高さ取得
int height() const;
///VRAM取得
unsigned* videoMemory();
///Frameworkに終了命令を出す
void requestEnd();
///Frameworkに終了命令が出ているか調べる
bool isEndRequested() const;
//以下ライブラリ使用者は知らなくていい
void start( void* windowHandle );
void preUpdate();
void postUpdate();
static void create();
static void destroy();
};
//cinのラッパ
class StandardInput{
public:
StandardInput();
StandardInput& operator>>( char& );
private:
bool mPrevEnterOn;
};
extern StandardInput cin;
} //namespace GameLib
#include "DebugStream.h"
#endif
こちらがDebugStreamです。
#ifndef INCLUDED_GAMELIB_DEBUGSTREAM_H
#define INCLUDED_GAMELIB_DEBUGSTREAM_H
#include <string>
using namespace std;
namespace GameLib{
class RefString;
class OStringStream;
//デバグアウトにcoutで出すためのもの
//複数スレッドから同時に呼んでも良い
class DebugStream{
public:
DebugStream();
int precision( int );
DebugStream& operator<<( char );
DebugStream& operator<<( unsigned char );
DebugStream& operator<<( int );
DebugStream& operator<<( unsigned );
DebugStream& operator<<( short );
DebugStream& operator<<( unsigned short );
DebugStream& operator<<( float );
DebugStream& operator<<( double );
DebugStream& operator<<( const string& );
DebugStream& operator<<( const char* );
DebugStream& operator<<( char* );
DebugStream& operator<<( const RefString& );
DebugStream& operator<<( const OStringStream& );
DebugStream& operator<<( DebugStream& ( *f )( DebugStream& ) );
DebugStream& endl();
DebugStream& hex();
DebugStream& dec();
void begin();
void end();
private:
class Impl;
Impl* mImpl;
};
DebugStream& endl( DebugStream& );
DebugStream& hex( DebugStream& );
DebugStream& dec( DebugStream& );
extern DebugStream cout;
} //namespace GameLib
#endif
ちなみに、
int main(){
Framework framework;
while(true){
framework.update();
}
}
という構成でmain()はライブラリの中に隠れていると考えればよい
と本に書いてありました。
ライブラリの追加はプロパティのリンカで
追加のライブラリと追加の依存ファイルに
入力すればでよろしいのでしょうか?
エラーがこの3つ以外出てないんですが二重定義は
ひっかかってるのでしょうか?
こちらがFrameworkです。
#ifndef INCLUDED_GAMELIB_FRAMEWORK_H
#define INCLUDED_GAMELIB_FRAMEWORK_H
namespace GameLib{
class Framework{
public:
Framework();
///ユーザ定義関数。これを書く。
void update();
///インスタンス取得
static Framework instance();
///画面幅取得
int width() const;
///画面高さ取得
int height() const;
///VRAM取得
unsigned* videoMemory();
///Frameworkに終了命令を出す
void requestEnd();
///Frameworkに終了命令が出ているか調べる
bool isEndRequested() const;
//以下ライブラリ使用者は知らなくていい
void start( void* windowHandle );
void preUpdate();
void postUpdate();
static void create();
static void destroy();
};
//cinのラッパ
class StandardInput{
public:
StandardInput();
StandardInput& operator>>( char& );
private:
bool mPrevEnterOn;
};
extern StandardInput cin;
} //namespace GameLib
#include "DebugStream.h"
#endif
こちらがDebugStreamです。
#ifndef INCLUDED_GAMELIB_DEBUGSTREAM_H
#define INCLUDED_GAMELIB_DEBUGSTREAM_H
#include <string>
using namespace std;
namespace GameLib{
class RefString;
class OStringStream;
//デバグアウトにcoutで出すためのもの
//複数スレッドから同時に呼んでも良い
class DebugStream{
public:
DebugStream();
int precision( int );
DebugStream& operator<<( char );
DebugStream& operator<<( unsigned char );
DebugStream& operator<<( int );
DebugStream& operator<<( unsigned );
DebugStream& operator<<( short );
DebugStream& operator<<( unsigned short );
DebugStream& operator<<( float );
DebugStream& operator<<( double );
DebugStream& operator<<( const string& );
DebugStream& operator<<( const char* );
DebugStream& operator<<( char* );
DebugStream& operator<<( const RefString& );
DebugStream& operator<<( const OStringStream& );
DebugStream& operator<<( DebugStream& ( *f )( DebugStream& ) );
DebugStream& endl();
DebugStream& hex();
DebugStream& dec();
void begin();
void end();
private:
class Impl;
Impl* mImpl;
};
DebugStream& endl( DebugStream& );
DebugStream& hex( DebugStream& );
DebugStream& dec( DebugStream& );
extern DebugStream cout;
} //namespace GameLib
#endif
ちなみに、
int main(){
Framework framework;
while(true){
framework.update();
}
}
という構成でmain()はライブラリの中に隠れていると考えればよい
と本に書いてありました。
ライブラリの追加はプロパティのリンカで
追加のライブラリと追加の依存ファイルに
入力すればでよろしいのでしょうか?
Re:エラーで3週間ぐらい悩んでます。
めるぽんさんありがとうございます。
勉強させていただきました。
本に沿ってこうなったのですが、プログラムにたりないものはありますか?
ほかのサンプルを乗せても同じエラーが出ます。
これはテキストデータです。
#####
. #
# o o #
# op# #
# # #
#.###.
### ###
勉強させていただきました。
本に沿ってこうなったのですが、プログラムにたりないものはありますか?
ほかのサンプルを乗せても同じエラーが出ます。
これはテキストデータです。
#####
. #
# o o #
# op# #
# # #
#.###.
### ###
Re:エラーで3週間ぐらい悩んでます。
Framework クラス内に、update.cpp の Frameworkd::update() 内で使っている getInput() と updateGame() と draw() の宣言がどこにもありませんね。それが原因でエラーが出ているようです。
これらは何を呼び出したつもりなのでしょうか。
というより、もしかして update.cpp って使うつもりのないソースだったりしませんか?
それならソースツリーから除けてしまえば解決しそうですけど...。
これらは何を呼び出したつもりなのでしょうか。
というより、もしかして update.cpp って使うつもりのないソースだったりしませんか?
それならソースツリーから除けてしまえば解決しそうですけど...。
Re:エラーで3週間ぐらい悩んでます。
ありがとうございます。
updateは
ライブラリのクラスの中身のイメージがありまして
class Framework{
public:
void update();
static int width();
static int height();
static unsigned* videoMemory();
}
これの
「三つは使い方を覚えて、残りの一つのupdateは自分で入力して作成しよう」と書いてありました。
それでupdateを作成したんですが、何か違いましたかね?
updateを外すとこんな感じのエラーがでてきます。
>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::fpos<int> __thiscall std::basic_istream<char,struct std::char_traits<char> >::tellg(void)" (?tellg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAE?AV?$fpos@H@2@XZ) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_istream<char,struct std::char_traits<char> > & __thiscall std::basic_istream<char,struct std::char_traits<char> >::seekg(long,int)" (?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@JH@Z) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: __thiscall std::basic_ifstream<char,struct std::char_traits<char> >::basic_ifstream<char,struct std::char_traits<char> >(char const *,int,int)" (??0?$basic_ifstream@DU?$char_traits@D@std@@@std@@QAE@PBDHH@Z) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::locale::facet * __thiscall std::locale::facet::_Decref(void)" (?_Decref@facet@locale@std@@QAEPAV123@XZ) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>libcpmtd.lib(ios.obj) : error LNK2005: "private: static void __cdecl std::ios_base::_Ios_base_dtor(class std::ios_base *)" (?_Ios_base_dtor@ios_base@std@@CAXPAV12@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(ios.obj) : error LNK2005: "public: static void __cdecl std::ios_base::_Addstd(class std::ios_base *)" (?_Addstd@ios_base@std@@SAXPAV12@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "void __cdecl _AtModuleExit(void (__cdecl*)(void))" (?_AtModuleExit@@YAXP6AXXZ@Z) は既に msvcprtd.lib(locale0_implib.obj) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: __Fac_tidy は既に msvcprtd.lib(locale0_implib.obj) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static void __cdecl std::locale::facet::facet_Register(class std::locale::facet *)" (?facet_Register@facet@locale@std@@CAXPAV123@@Z) は既に msvcprtd.lib(locale0_implib.obj) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static class std::locale::_Locimp * __cdecl std::locale::_Getgloballocale(void)" (?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static class std::locale::_Locimp * __cdecl std::locale::_Init(void)" (?_Init@locale@std@@CAPAV_Locimp@12@XZ) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_ctor(class std::_Locinfo *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_dtor(class std::_Locinfo *)" (?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::_Lockit(int)" (??0_Lockit@std@@QAE@H@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::~_Lockit(void)" (??1_Lockit@std@@QAE@XZ) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>LINK : warning LNK4098: defaultlib 'LIBCMTD' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
1>MSVCRTD.lib(crtexe.obj) : error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。
1>C:\Users\admin\Documents\Visual Studio 2008\Projects\Project1\2dgraphic\Debug\2dgraphic.exe : fatal error LNK1120: 外部参照 1 が未解決です。
私の実力がないばかりにすみません。
updateは
ライブラリのクラスの中身のイメージがありまして
class Framework{
public:
void update();
static int width();
static int height();
static unsigned* videoMemory();
}
これの
「三つは使い方を覚えて、残りの一つのupdateは自分で入力して作成しよう」と書いてありました。
それでupdateを作成したんですが、何か違いましたかね?
updateを外すとこんな感じのエラーがでてきます。
>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::fpos<int> __thiscall std::basic_istream<char,struct std::char_traits<char> >::tellg(void)" (?tellg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAE?AV?$fpos@H@2@XZ) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_istream<char,struct std::char_traits<char> > & __thiscall std::basic_istream<char,struct std::char_traits<char> >::seekg(long,int)" (?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@JH@Z) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: __thiscall std::basic_ifstream<char,struct std::char_traits<char> >::basic_ifstream<char,struct std::char_traits<char> >(char const *,int,int)" (??0?$basic_ifstream@DU?$char_traits@D@std@@@std@@QAE@PBDHH@Z) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::locale::facet * __thiscall std::locale::facet::_Decref(void)" (?_Decref@facet@locale@std@@QAEPAV123@XZ) は既に GameLib_d.lib(Manager.obj) で定義されています。
1>libcpmtd.lib(ios.obj) : error LNK2005: "private: static void __cdecl std::ios_base::_Ios_base_dtor(class std::ios_base *)" (?_Ios_base_dtor@ios_base@std@@CAXPAV12@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(ios.obj) : error LNK2005: "public: static void __cdecl std::ios_base::_Addstd(class std::ios_base *)" (?_Addstd@ios_base@std@@SAXPAV12@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "void __cdecl _AtModuleExit(void (__cdecl*)(void))" (?_AtModuleExit@@YAXP6AXXZ@Z) は既に msvcprtd.lib(locale0_implib.obj) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: __Fac_tidy は既に msvcprtd.lib(locale0_implib.obj) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static void __cdecl std::locale::facet::facet_Register(class std::locale::facet *)" (?facet_Register@facet@locale@std@@CAXPAV123@@Z) は既に msvcprtd.lib(locale0_implib.obj) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static class std::locale::_Locimp * __cdecl std::locale::_Getgloballocale(void)" (?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "private: static class std::locale::_Locimp * __cdecl std::locale::_Init(void)" (?_Init@locale@std@@CAPAV_Locimp@12@XZ) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_ctor(class std::_Locinfo *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_dtor(class std::_Locinfo *)" (?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::_Lockit(int)" (??0_Lockit@std@@QAE@H@Z) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>libcpmtd.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::~_Lockit(void)" (??1_Lockit@std@@QAE@XZ) は既に msvcprtd.lib(MSVCP90D.dll) で定義されています。
1>LINK : warning LNK4098: defaultlib 'LIBCMTD' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
1>MSVCRTD.lib(crtexe.obj) : error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。
1>C:\Users\admin\Documents\Visual Studio 2008\Projects\Project1\2dgraphic\Debug\2dgraphic.exe : fatal error LNK1120: 外部参照 1 が未解決です。
私の実力がないばかりにすみません。
Re:エラーで3週間ぐらい悩んでます。
それは何かよく見るエラーですね。
プロジェクトを右クリックして「プロパティ」→「C/C++」→「コード生成」→「ランタイム ライブラリ」
が多分「マルチスレッド デバッグ DLL」になってませんかね?
そうだとすれば「マルチスレッド デバッグ」にすればいいかも。
プロジェクトを右クリックして「プロパティ」→「C/C++」→「コード生成」→「ランタイム ライブラリ」
が多分「マルチスレッド デバッグ DLL」になってませんかね?
そうだとすれば「マルチスレッド デバッグ」にすればいいかも。
Re:エラーで3週間ぐらい悩んでます。
マルチスレッド デバッグ (/MTd)
にしたらエラーがだいぶ減って
1>LIBCMTD.lib(crt0.obj) : error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。
1>C:\Users\admin\Documents\Visual Studio 2008\Projects\Project1\2dgraphic\Debug\2dgraphic.exe : fatal error LNK1120: 外部参照 1 が未解決です。
エラー2
というあんまり見ないエラー二つになりました。
frameworkに
///ユーザ定義関数。これを書く。
void update();
と書いてるんですが、これはやはりupdate.cppでつくったほうがいいんですかね?
けれど、作るとまた最初の3つのエラーに悩まされるんですよね.....
にしたらエラーがだいぶ減って
1>LIBCMTD.lib(crt0.obj) : error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。
1>C:\Users\admin\Documents\Visual Studio 2008\Projects\Project1\2dgraphic\Debug\2dgraphic.exe : fatal error LNK1120: 外部参照 1 が未解決です。
エラー2
というあんまり見ないエラー二つになりました。
frameworkに
///ユーザ定義関数。これを書く。
void update();
と書いてるんですが、これはやはりupdate.cppでつくったほうがいいんですかね?
けれど、作るとまた最初の3つのエラーに悩まされるんですよね.....
Re:エラーで3週間ぐらい悩んでます。
ああ、そういえば main 関数無かったですね。先ほど書かれていたように、main.cpp のどこかに
> ///ユーザ定義関数。これを書く。
> void update();
既に main.cpp で update() の定義を書いているため、
update.cpp でさらに書くと多重定義でエラーになるので、どちらかしか書いてはいけません。
int main(){ Framework framework; while(true){ framework.update(); } }とか書いておけばよかったりしませんかね?
> ///ユーザ定義関数。これを書く。
> void update();
既に main.cpp で update() の定義を書いているため、
update.cpp でさらに書くと多重定義でエラーになるので、どちらかしか書いてはいけません。
Re:エラーで3週間ぐらい悩んでます。
ありがとうございますエラーがなくなりました!
しかし、
int main(){
Framework framework;
while(true){
framework.update();
}
}
を入れたところエラーがなくなったんですが、
起動するとすぐにプログラムが動作を停止して
ウィンドウに「続行するには何かキーを押してください」
みたいな文字が表示される状態になりました。
情報が少ないのですが、何が足りないのでしょうか?
しかし、
int main(){
Framework framework;
while(true){
framework.update();
}
}
を入れたところエラーがなくなったんですが、
起動するとすぐにプログラムが動作を停止して
ウィンドウに「続行するには何かキーを押してください」
みたいな文字が表示される状態になりました。
情報が少ないのですが、何が足りないのでしょうか?