2015-03-07 5 views
0

У меня есть класс ModelManager, который получен из класса шаблонов 'TModelManager'. Их декларация выглядит следующим образом:Статический член базового класса шаблона не экспортируется в общую библиотеку

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> 
{ 
    [...] 
}; 

Существует две разделяемые библиотеки: «общий» и «сервер».

В "общей" библиотеке DLLNETWORK эквивалентна '__attribute __ ((видимость (по умолчанию)))' на системах 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; 

В «сервера» -library, DLLNETWORK пустое определение, чтобы убедиться, что класс импортируется. «Сервер» -библиотека связана с «общей» -библиотекой.

Это компилирование просто отлично.

Во время выполнения -library «сервер» загружается в динамически, что также приводит к «общим» -library быть загружен в Тем не менее, это приводит к следующей ошибке:.

Unable to load library 'lib/libserver_x64.so': lib/libserver_x64.so: undefined symbol: _ZN13TModelManagerI5Model9ModelMesh12ModelSubMeshE8m_markedE 

I» ve использовала утилиту «ldd» на «server» -библиотеке, которая подтверждает, что она связана с «общей» -библиотекой и может ее найти.

Я использовал утилиту «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» -member встречается дважды с другим адресом.

Я действительно вообще этого не понимаю, член «m_marked» определяется так же, как и элемент «m_models», так почему он не экспортируется? Почему член «m_models» появляется дважды?

// EDIT:

я не заметил «U» перед нм результатов для «m_models», что означает, что они не определены.

Что-то не так с моим определением?

ответ

2

The members of the template class are defined as such (in a cpp-file):

Вы, кажется, предполагая, что эти определения будут создаваться в файле CPP, но если что-то в этом CPP файл не использует их члены будут не быть создан, и поэтому соответствующие символы не будут генерироваться в скомпилированном объектном файле.

Код в серверной библиотеке, которая использует эти статические члены, не может имплицитно их создавать, поскольку вы скрыли определения в файле cpp.

Определения статического члена должны быть явно созданы для всех специализированных специализаций, или вам нужно поместить эти определения в заголовок.