simongeilfus / Cinder-Runtime

Runtime-Compiled C++ for Cinder
57 stars 43 forks source link

intermittent linker errors about missing operator new / delete on reload #20

Closed richardeakin closed 6 years ago

richardeakin commented 6 years ago

@simongeilfus is aware of this issue but I wanted to document it here. I've seen it in two very different scenarios, and unfortunately it doesn't seem to be a consistent problem. The problem is that somehow the runtime version is expected to have overloaded operator new and delete, but currently these only exist on the statically compiled class. Resulting error message:

   Creating library D:\code\rte\mawork\test\MaTests\proj\vc2015\build\x64\Debug_Shared\v140\intermediate\runtime\WispController\build\WispController.lib and object D:\code\rte\mawork\test\MaTests\proj\vc2015\build\x64\Debug_Shared\v140\intermediate\runtime\WispController\build\WispController.exp
WispSimTest.obj : error LNK2019: unresolved external symbol "public: static void * __cdecl WispController::operator new(unsigned __int64)" (??2WispController@@SAPEAX_K@Z) referenced in function "public: __cdecl WispSimTest::WispSimTest(void)" (??0WispSimTest@@QEAA@XZ)
WispSimTest.obj : error LNK2019: unresolved external symbol "public: static void __cdecl WispController::operator delete(void *)" (??3WispController@@SAXPEAX@Z) referenced in function "int `public: __cdecl WispSimTest::WispSimTest(void)'::`1'::dtor$9" (?dtor$9@?0???0WispSimTest@@QEAA@XZ@4HA)
D:\code\rte\mawork\test\MaTests\proj\vc2015\build\x64\Debug_Shared\v140\intermediate\runtime\WispController\build\WispController.dll : fatal error LNK1120: 2 unresolved externals

We thought it might be that RT_COMPILED wasn't defined for the reloaded version, but it appears that it is as expected. To test (and after finding the Compiler's verbose flag that you need to enable to see the output), I add the following to my header.

#if ! defined( RT_COMPILED )
#pragma message ( __FILE__  " | Blarg 1 RT_COMPILED not defined" )
#else
#pragma message ( __FILE__  " | Blarg 1 RT_COMPILED is defined" )
#endif

#include "runtime/ClassWatcher.h"

class WispController {
  RT_DECL
...

.. and RT_COMPILED is always defined during the runtime reload.

We think this problem might go away after a few updates Simon has planned, which would make it so the static and RT compiled versions of a class contain the same overloaded methods (perhaps their implementation is different? I don't know).

richardeakin commented 6 years ago

Update on this: we found that the problem could be avoided if you set rt::BuildSettings().linkAppObjs( false ), which indicates that some other .obj file still had the old symbol of the reloadable class. In this case, it was WispSimTest.obj (the 'host' object) that contained symbols also in WispController.dll.

simongeilfus commented 6 years ago

This should be fixed, let me know if you're still seeing something wrong.