Hi,
I'm trying to integrate RCCPP into my own engine, which has it's own object factories and per module interfaces, and therefore I'm trying to see and understand how much of the RuntimeObjectSystem needs to be recoded to suit my engine, and to do that, I need to understand how the underlying things work.
This is the process that I'm going through in my head right now as to how this works at a lower level. Do let me know if there's something very wrong here.
At Program Initialization/Startup:
- Keep track of all dependent build header/cpp files via the macro REGISTERCLASS(RuntimeObject01).
Example:
Macro REGISTERCLASS expands to find all associated RuntimeIncludeFiles, RuntimeSourceDependency, and RuntimeLinkLibrary. TObjectConstructorConcrete constructs itself, calling PerModuleInterface::GetInstance() in the process. Due to this, ObjectInterfacePerModuleSource.cpp is added as a RuntimeIncludeFile, which contains definitions to PerModuleInterface.
At Program Runtime:
1) File for source code changes. Assume RuntimeObject01's source is changed for the following steps.
2) Use the dependent files that we gathered earlier as arguments for the build tool, building to a temporary file.
3) Call LoadLibraryA() on the temporary file and getting the module's handle.
As a side effect, due to additional code being loaded into the program's memory space, the REGISTERCLASS macro declares objects in the global scope and the object is registered again. Thus, another different PerModuleInterface is instantiated, but in a different memory space that is not the original program's.
4) Call GetProcAddress(modulehandle, "GetPerModuleInterface"); to get the function that returns the PerModuleInterface, which provides new calls to the newly merged dll's
5) Serialize all associated objects, reconstruct all objects, then deserialize them again, and reassign any additional pointers through the callback OnConstructorsAdded().
So if I'm understanding this correctly, some conclusions can be made here:
a) Code used for static libraries should also work with this method.
b) The memory leak is caused by the fact you simply no longer reference the old PerModuleInterface structures and functions.
c) MSVC's call stack will show something like A32B.tmp!RuntimeObject01::Update(), followed by ConsoleExample.exe!ConsoleGame::MainLoop. The temp file references the dll that you built in 2).
d) Step (5) can essentially be considered as replacing ALL references to the old objects, hence (b). So if A.cpp classes has pointers to B.cpp classes and B is runtime compiled, changing B.cpp would require an update of A.cpp's pointers to B.cpp's classes.
Anyway, thanks for setting this up; this is some really good learning material to work with.
Thanks,
Deng