メガエディット 3000
未定義の参照の原因を発見しました。シンボルの .o ファイルをチェックしましたが、それらが欠落していました。そこにいなかっただけです。明らかな理由はありません。侵害した .o ファイルのソースを確認しましたが、すべて問題ないようでした。私は、これは厄介な#ifdef ... #endif
ブロックの 1 つで、クマのわなのようにコード行の間に巧妙に隠され、犠牲者を待っているのではないかと考えました。しかし、私は何も見つけることができませんでした。#ifdef ... #endif
一部の関数定義をファイルの最後に移動し、それらを Linux に適したブロックで囲むと、シンボルが魔法のように表示され、すべて問題ありませんでした。お時間をいただきありがとうございます。
古いので読まないでください。
私は最近、1 つの大きなプロジェクトに割り当てられました。私の仕事は、Linux プラットフォームで実行することです。残念なことに、私の前にプロジェクト全体を書いたプログラマーは非常に貧弱な仕事をしており
B3D_Base.h
、ほぼすべてのヘッダーが#included
である file を、プロジェクト内のほぼすべてのヘッダーとソース ファイルにインクルードすることで、大量の循環依存関係を作成しました (これにより、170 以上のファイルが#include "B3D_Base.h"
ライン)。これにより、Windows と Linux の両方でコンパイル中に問題が発生することはありませんでした。ただし、これにより、すべてのオブジェクト ファイルとライブラリがリンクされているにもかかわらず、Linux でのリンク フェーズ中に多くの「未定義の参照」エラーが発生します。
リンク中のすべてのオブジェクトファイルの単一反復の制限を認識してld
、私は尋ねています:
オブジェクトとライブラリを介して複数の反復を強制的ld
に実行し、700 以上の未定義の参照エラーをすべて解決する方法はありますか、または#include "B3D_Base.h"
必要なヘッダーへの適切なインクルードですべての行を置き換えるだけでプロジェクトを実際にリンクする唯一のチャンスですか?
付録1:
以下は、Linux で実行することになっている混乱の例です。
class を含む1 つのヘッダー ファイルB3D_Base.h
がインクルードされます。ファイルはBase に含まれていないメモリ マネージャ クラスのみを含んでいます。インスタンスはで宣言され、プロジェクトの他の多くの部分で初期化+使用されます。すべて問題なくコンパイルできますが、リンクに関しては多くのエラーが発生します。そして、このようなエラーは他にもたくさんあり、クラス インスタンスと関数の両方への未定義の参照について不平を言っています。きれいなコードはこれで終わりです。B3D_Loading3.h
B3D_LOADING3
B3D_Loading3.cpp
B3D_Base.h
B3D_LOADING3 g_Loading3;
B3D_Base.h
'undefined reference to g_Loading3'
付録 2:
kfsone が要求したように、SSCCE の例を提供します。
B3D_Base.h
... (many other includes)
#include "B3D_Loading3.h"
extern B3D_LOADING3 g_Loading3;
... (includes go on)
B3D_Loading3.h/B3D_Loading.cpp
a full definition of class B3D_LOADING3, but no real declaration of g_Loading3
AW_Game.cpp (g_Loading3 が使用されるファイルの 1 つ)
#include "B3D_Base.h"
... (some lines)
extern B3D_LOADING3 g_Loading3;
コードを徹底的に調べさせてくれた kfsone のおかげで、どこに問題があるのかを突き止めることができました。g_Loading3 はどこでも として定義されてextern
いるため、適切に定義されていません。extern
必要なのは、1 つのファイルからキーワードを削除することだけでした。~ 30 個のリンク エラーを修正しました。ありがとう、kfsone。
付録 3:
しかし、クラス関数への未定義の参照にはまだ問題があります。いくつかのコードをスキャンした後、#ifdef ... #endif
句の過度の使用 (移植性) のために関数が定義されていないと思います。したがって、受動的な ifdef ブロックでのみ定義された関数を見落としているのは私のせいかもしれません。この問題を調べて、何か変更があれば後で報告します。
付録 3 レポート:
関数を適切に定義した後でも、undefined-reference-list は縮小しませんでした。したがって、この問題はまだ議論の余地があります。
付録 #3.1
いくつかのサンプルコードを提供します。
フー。
#ifndef FOO_H
#define FOO_H
class Foo
{
unsigned int m_size;
bool m_lock;
friend class ASDF;
public:
unsigned int m_id;
void Release() {delete this;}
int Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags);
int Unlock();
};
// other class declarations to follow
#endif
Foo.cpp
#include "Foo.h"
// other includes and function definitions to follow
int Foo::Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags)
{
if(!m_lock)
{
// some locking code
}
return 0;
}
Baz.cpp
#include "Foo.h" // although included, defined and declared, causes undef reference
Foo *m_pFoo;
// several lines later
m_pFoo->Lock(0,0,(void)&Asdf,NULL); // <-- compiles fine, causes undefined reference