テンプレートクラス「TModelManager」から派生したクラス「ModelManager」があります。彼らの宣言は次のとおりです。
template<class TModel,class TModelMesh,class TModelSubMesh>
class TModelManager
{
protected:
static std::map<std::string,ModelHandle> m_models;
static std::vector<std::map<std::string,ModelHandle>::iterator> m_marked;
[...]
};
class DLLNETWORK ModelManager
: public TModelManager<Model,ModelMesh,ModelSubMesh>
{
[...]
};
「共有」と「サーバー」という 2 つの共有ライブラリがあります。
「共有」ライブラリでは、DLLNETWORK は '__attribute__((visibility("default")))' に相当し、Linux システムではクラスをエクスポートします。テンプレート クラスのメンバーは次のように定義されます (cpp ファイル内)。
template<class TModel,class TModelMesh,class TModelSubMesh>
DLLNETWORK std::map<std::string,ModelHandle> TModelManager<TModel,TModelMesh,TModelSubMesh>::m_models;
template<class TModel,class TModelMesh,class TModelSubMesh>
DLLNETWORK std::vector<std::map<std::string,ModelHandle>::iterator> TModelManager<TModel,TModelMesh,TModelSubMesh>::m_marked;
「サーバー」ライブラリでは、クラスが確実にインポートされるように、DLLNETWORK は空の定義です。「サーバー」ライブラリは、「共有」ライブラリに対してリンクされています。
これは問題なくコンパイルされています。
実行時に、「サーバー」ライブラリが動的に読み込まれ、「共有」ライブラリも読み込まれます。ただし、次のエラーが発生します。
Unable to load library 'lib/libserver_x64.so': lib/libserver_x64.so: undefined symbol: _ZN13TModelManagerI5Model9ModelMesh12ModelSubMeshE8m_markedE
「サーバー」ライブラリで「ldd」ユーティリティを使用しました。これにより、「共有」ライブラリに対してリンクされていることが確認され、それを見つけることができます。
次に、「nm」ユーティリティを使用して、TModelManager クラスに関連するすべてのシンボルを探しました。結果は次のとおりです。
nm -D libshared_x64.so | grep ModelManager
0000000000b15610 u _ZGVN13TModelManagerI5Model9ModelMesh12ModelSubMeshE8m_modelsE
000000000072d1b0 T _ZN12ModelManager21CreateFromBrushMeshesERSt6vectorIP9BrushMeshSaIS2_EE
000000000072d10c T _ZN12ModelManager4LoadESs
000000000072d950 W _ZN13TModelManagerI5Model9ModelMesh12ModelSubMeshE21CreateFromBrushMeshesERSt6vectorIP9BrushMeshSaIS6_EE
000000000072d62c W _ZN13TModelManagerI5Model9ModelMesh12ModelSubMeshE4LoadESsPFP8MaterialPKcE
0000000000b155e0 u _ZN13TModelManagerI5Model9ModelMesh12ModelSubMeshE8m_modelsE
「m_marked」メンバーを除いて、すべてがそこにあります。「m_models」メンバーが異なるアドレスで 2 回見つかりました。
私は本当にこれをまったく理解していません.「m_marked」メンバーは「m_models」メンバーと同じ方法で定義されているのに、なぜエクスポートされないのですか? 「m_models」メンバーが 2 回表示されるのはなぜですか?
// 編集:
「m_models」の nm-results の前にある「U」に気づきませんでした。これは、それらが未定義であることを意味します。
それらを定義するのに何か問題がありますか?