Not sure about object files, but you could simply compile box2d to its own shared library (.dll file). Then it will work fine across reloads.
If you don't care about API boundaries/layering and just want it to work, then compile the Box2d implementation into the non-reloaded code (i.e. the platform layer in HMH). Your Box2d usage code can live in your reloaded-code just fine.
1 2 | add_library(box2d SHARED ${box2d_directory}) target_link_libraries(game ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} ${SDL2_MIXER_LIBRARY} ${OPENGL_LIBRARIES} ${box2d}) |
1 2 | add_library(box2d SHARED ${box2d_directory}) target_link_libraries(game ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} ${SDL2_MIXER_LIBRARY} ${OPENGL_LIBRARIES} box2d) |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Use a dummy type if you don't want the no-op constructor to collide with real ones. static const struct FixVirtualMethodTable {} FIX_VIRTUAL_METHOD_TABLE = {}; class IFoo { public: explicit IFoo(const FixVirtualMethodTable _) {} public: virtual void foo() = 0; }; fread(blob, 1, size_of_blob, serialized); new (blob) IFoo(FIX_VIRTUAL_METHOD_TABLE); |
mtwilliams
If you do find yourself fiddling with Box2D's internals or wanting to hot-reload other code that uses virtual method tables, you can always patch the pointer in each instance using a special constructor and placement new:
1 2 3 4 5 6 7 8 9 10 11 12 13 // Use a dummy type if you don't want the no-op constructor to collide with real ones. static const struct FixVirtualMethodTable {} FIX_VIRTUAL_METHOD_TABLE = {}; class IFoo { public: explicit IFoo(const FixVirtualMethodTable _) {} public: virtual void foo() = 0; }; fread(blob, 1, size_of_blob, serialized); new (blob) IFoo(FIX_VIRTUAL_METHOD_TABLE);
PhysX, does this for example. I believe Bungie did this when dealing with Havok and their tag system (they pretty much malloc + fread everything in). So not pretty, but not unprecedented.