0

I'm trying to create an Asset Manager that loads different types based on some reflection data, so that I can call something like GetAsset(uint16_t assetType, Uuid uuid). I do not want to use strings due to performance worries. The system I have works well within a single binary, but not across libraries. What is a good way to register types dynamically across libraries?

The current way I handle this is by using the following strategy. I have a static member variable in each struct:

struct TextureAsset : public Asset {
    TextureAsset(Uuid uuid, std::string_view name, Texture* texture) : Asset(uuid, name), texture(texture) {}
    Texture* texture = nullptr;

    static uint16_t assetType;
};

I then set the static variable from an AssetManager:

private uint16_t assetTypeNames;

template <typename AssetT, typename AssetImporterT>
void RegisterAssetType() {
    AssetT::assetType = (AssetType)assetTypeNames.size();
}

Both TextureAsset and AssetManager are in the same library, EngineCore.dll. I also have a file EntryPoint.cpp in a library called Renderables3d.dll, and when I try to reference the member variable:

uint16_t assetType = TextureAsset::assetType;

I get this error in the file in EntryPoint.cpp:

unresolved external symbol "public: static unsigned short TextureAsset::assetType" (?assetType@TextureAsset@@2GA)

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • 1
    I suppose you could package your asset manager as yet another DLL, so all the DLLs can depend on it. – Igor Tandetnik Mar 03 '23 at 22:43
  • The asset manager is part of my program Core DLL. But that still won't help with referencing the assetType static member variable. – Karim Abdel Hamid Mar 03 '23 at 22:50
  • That unresolved external symbol error you cite - when is it reported? For which module being linked? Does that module actually define the static member, in addition to declaring it? Recall that a static member must be defined in one source file, like this: `uint16_t TextureAsset::assetType;` , in addition to being declared in the class definition. – Igor Tandetnik Mar 03 '23 at 23:24
  • It's called in a cpp file in the EngineCore.dll, and the error comes from its reference in a different library, Renderables3d.dll. AssetType TextureAsset::assetType; – Karim Abdel Hamid Mar 03 '23 at 23:50
  • Looks like your design ended up with circular dependencies: `TextureAsset` et al depends on asset manager, but asset manager depends on every asset, because apparently somewhere in asset manager implementation you have `RegisterAssetType(); RegisterAssetType(); ...` It may be wise to break that circular dependency by requiring each asset to register itself. That is, expose `RegisterAssetType` is a public method on asset manager (implemented as a singleton, I imagine), and have each asset call `RegisterAssetType` on itself, from its own DLL. – Igor Tandetnik Mar 04 '23 at 00:01
  • I'm sorry, I haven't been clear enough about where my actual issue is because, well, I'm rather tired of this issue. I am considering your point, but right now RegisterAssetType isn't the heart of the issue. The type I've set the static variable of is in the same library as the AssetManager, in EngineCore.dll. Now I want to access that type in Renderables3d.dll so I can use it in a different struct. I will reform my original question to be clearer. – Karim Abdel Hamid Mar 04 '23 at 01:21
  • Does this answer your question? [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Mar 04 '23 at 01:40
  • @KenWhite I've skimmed through it and although it does refer to exporting classes as a whole, I can't find something about specifically how to export a static class member across DLL boundaries. – Karim Abdel Hamid Mar 04 '23 at 12:11

0 Answers0