3

これはおそらく千回も聞かれていることは知っていますが、私はこの数日間、この質問に釘を刺しています. 私は C++ の初心者で、Visual Studio を使用するのはこれが初めてです。

大学での競技用に TORCS Racing Simulator を改造しようとしています。これのほとんどは既に行われているので、私が投稿しているものの一部だけが実際に私のコードです。しかし、それにいくつかの新しい機能を追加しましたが、それらに問題があります。

Linux では g++ を使用してすべて正常に動作しましたが、Visual Studio 2005 でコンパイルしようとすると、未解決の外部シンボル エラーが発生します。

他のプロジェクトの関数を使用する新しいプロジェクトをソリューションに追加しました。

この新しいプロジェクトでは、次の関数を呼び出します。

getisDerbyDuel()

raceinit.hこれは、新しいプロジェクトに含めた で宣言されています。

#ifndef _RACEINIT_H_
#define _RACEINIT_H_

#define RACE_ENG_CFG    "config/raceengine.xml"

extern void ReInit(void);
extern void ReShutdown(void);
extern void ReStartNewRace(void * /* dummy */);
extern void ReAddRacemanListButton(void *menuHandle);
extern int  ReInitCars(void);
extern int  ReInitTrack(void);
extern void ReRaceCleanup(void);
extern void ReRaceCleanDrivers(void);
extern char *ReGetCurrentRaceName(void);
extern char *ReGetPrevRaceName(void);
extern bool getisDerbyDuel(void);
extern void setisDerbyDuel(bool isDerbyDuel);

extern tModList *ReRaceModList;

#endif /* _RACEINIT_H_ */

で定義されていraceinit.cppます:

 bool _isDerbyDuel = true;

void setisDerbyDuel(bool isDerbyDuel) {
    _isDerbyDuel = isDerbyDuel;
}
bool getisDerbyDuel(void) {
    return _isDerbyDuel;
}

raceinit.hとはraceinit.cpp、クライアントと呼ばれる私のソリューションの別のプロジェクトにあり、エラーなしでコンパイルされます。client.libプロジェクトの依存関係 にも追加しました。

コンパイルすると、次の出力が得られます。

1>Generating Code... 
1>Compiling resources...
1>Linking...
1>   Creating library .\Release/championship2010server.lib and object      .\Release/championship2010server.exp
1>championship2010server.obj : error LNK2019: unresolved external symbol "bool __cdecl     getisDerbyDuel(void)" (?getisDerbyDuel@@YA_NXZ) referenced in function "void     __cdecl drive(int,struct CarElt *,struct Situation *)"     (?drive@@YAXHPAUCarElt@@PAUSituation@@@Z)
1>.\Release/championship2010server.dll : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://c:\Users\Administrator\Desktop\torcs-verylasttry    \src\drivers\championship2012server\Release\BuildLog.htm"
1>championship2010server - 2 error(s), 9 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========    

どんなアイデアでも大歓迎ですが、もう何を試すべきかわかりません。


編集:

回答ありがとうございます。外部のものを変更しようとしたため、フラグ自体はヘッダーファイルで外部と宣言され、ゲッターはそうではありません(およびいくつかの組み合わせ)が、エラー出力を変更するものは何もないようです。

関数をエクスポートすることの意味が正確にはわかりません。簡単なGoogle検索でこれにたどり着きました:

[..]
extern void ReRaceCleanDrivers(void);
extern char *ReGetCurrentRaceName(void);
extern char *ReGetPrevRaceName(void);
#ifdef __cplusplus
extern "C" {  // only need to export C interface if
              // used by C++ source code
#endif
extern bool __declspec( dllimport ) getisDerbyDuel(void);
extern void __declspec( dllimport ) setisDerbyDuel(bool isDerbyDuel);

#ifdef __cplusplus
}
#endif
extern bool _isDerbyDuel;
[...]

extern "C" {
#include <raceinit.h>
}

エラー出力を次のように変更しました。

1>championship2010server.obj : error LNK2019: unresolved external symbol     __imp__getisDerbyDuel referenced in function "void __cdecl drive(int,struct CarElt *,struct     Situation *)" (?drive@@YAXHPAUCarElt@@PAUSituation@@@Z)
1>.\Release/championship2010server.dll : fatal error LNK1120: 1 unresolved externals

ここで何が悪いのかわかりません。


編集2:

そのため、関数のインポート/エクスポートについて読んだ後、コードを調整しました。
未解決の関数が宣言されているヘッダー ファイルは、次のようになります。

#ifdef __cplusplus
extern "C" {  // only need to export C interface if
              // used by C++ source code
#endif
 __declspec( dllexport ) bool getisDerbyDuel(void);
 __declspec( dllexport ) void setisDerbyDuel(bool isDerbyDuel);

#ifdef __cplusplus
}
#endif
extern bool _isDerbyDuel;

関数を呼び出すファイルにはヘッダー ファイルがありませんが、ファイル内の他の関数に従って、インポートされた関数を宣言しようとしました。

[...]
static tTrack *curTrack;
static int RESTARTING[NBBOTS];

static void initTrack(int index, tTrack* track, void *carHandle,
        void **carParmHandle, tSituation *s);
static void newrace(int index, tCarElt* car, tSituation *s);
extern "C" void drive(int index, tCarElt* car, tSituation *s);
static void endrace(int index, tCarElt *car, tSituation *s);
static void shutdown(int index);
static int InitFuncPt(int index, void *pt);

__declspec( dllimport ) bool getisDerbyDuel(void);
[...]

ヘッダーは他のものと同じようにインクルードされ、関数は次のように呼び出されます。

if (getisDerbyDuel()) {
[...]

エラー出力は次のように変更されました。

error LNK2019: unresolved external symbol _getisDerbyDuel referenced in function _drive

したがって、C/C++ の互換性の問題を解決しただけで (またはさらに悪化させた場合は、もう確信が持てません)、リンカの問題は変更されていないように思えます。

何か案は?私は今ちょっと先延ばしにしていますが、これを機能させる必要があります。そうしないと、上司が腹を立てます:)

4

2 に答える 2

7

私が言ったように、私は Visual Studio は初めてですが、これはまだ少し恥ずかしいです。エラーが見つかりましたが、実際にはコードにはありませんでした。
リンカー入力などに加えて、raceinit.cpp を含むプロジェクトを新しいプロジェクトの参照に追加する必要がありました。それは私の問題を解決しました。

于 2012-04-04T12:18:08.487 に答える
3

Visual Studioは、パスインクルードとライブラリリンクに異なる方法を使用します。

プロジェクト設定を確認します。

  1. プロジェクトを右クリックして、[設定]を選択します
  2. [構成プロパティ]の下の[C/C ++]の下で、必要なヘッダーへのパスが追加されていることを確認します
  3. 次に、[リンカー]で、[追加のライブラリディレクトリ]の下にあるlibファイルへのパスを追加したことを確認します。
  4. また、[リンカー]>[入力]>[追加の依存関係]の下にライブラリを追加したことを確認してください

上記がお役に立てば幸いです。

于 2012-04-02T16:58:37.010 に答える