I am using my own library within Unreal 4 and I seem to have a conflict issue with the delete operator.
20>libMyFramework.lib(MemBase.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPEAX@Z) already defined in MyPlugin.cpp.obj
20>libMyFramework.lib(MemBase.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPEAX@Z) already defined in MyPlugin.cpp.obj
the linker error only appears if I use one of my own dynamic arrays from my library - which is a templates class (all inlined). That class internally uses new and delete which are defined with their own allocator.
I have properly guarded my #include of my framework like this
UE4 overrides the operator new/delete operators to its own implementation, and your library seems to be being built against the standard library implementation, hence the clash.
My suggestion would be to convert your library to a UE4 module which will then automatically start to use those operator overloads, which are overridden in UE4’s IMPLEMENT_MODULE macro.
I cannot really convert my Library to a UE4 Module as it is used on my not unreal related applications on server side.
I am not at home right now so I can’t check out the IMPLEMENT_MODULE macro. Is there a way to let my Library use its own allocators ? (as stated above the new and delete are overriden Inside my Library too - so its not the standard allocators).
is there maybe some magic #define I can use to wrap my headers around to “protect” them from clashing with UE4 ?
Sorry, I didn’t notice that you said your library overrides operator new and delete too. That makes sense then. You simply need to not override them and the linker should use the UE4 overrides when you statically link your library.
There is no way to have two different operator new/deletes statically linked into the same program at the same time, just as the same as it’s not possible for any other function, so there’s no ‘magic’ available. This is not just a UE4 thing - it’s a C++ thing.
If you were adamant about keeping your own overrides then you could rebuild your library as a DLL and dynamically link it instead of statically linking it, as each DLL has its own operator new/delete.
However, this would tie your library to a Windows implementation - I don’t know if this is a problem for you. You’d also have to be sure that all of your new/deletes happened within your module and not inside UE4, as mismatched new/deletes would cause disaster. This can happen easily with templates (like container classes), as your module and the engine would each have their own instantiation of the container code which would call its own new/delete.
what you say makes sense I think.
My Library is Windows only yes so in theory DLL would be an option but I think I could also modify my build pipeline to spit out some UE4 specific Library that does’nt make use of my overrides.
if I do that, is there some caveats i need to think of before doing it ? I.e. are those new and delete operators meant to be used for UObjects or something like that ?
Those overrides are used for every new/delete in UE4, not just UObjects.
I would go with a define like DISABLE_OPERATOR_OVERRIDES and then use that to build a variant of your library which can link against UE4… but it’s not a UE4-specific problem so doesn’t make sense to name the macro after UE.
Libraries which override operator new/delete is a bit ‘rude’ anyway, because it forces everything else being (statically) linked to use your operators.
As a quick side note, you will get a very similar error reported if you put your PCH include after anything else.
>MyModule.cpp.obj : error LNK2005: "void * __cdecl operator new(unsigned __int64)" (??2@YAPEAX_K@Z) already defined in MyModule.h.obj
>MyModule.cpp.obj : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPEAX@Z) already defined in MyModule.h.obj
The compiler appears to do some initialization including finding new and delete, which rolls over until it is overwritten by UE4. It is remedied by simply including your PCH first.
If somebody has linker errors related to new and delete already being declared, it’s sometimes due to adding “;” to the end of Macro lines, like declaration of Log Categories
DECLARE_LOG_CATEGORY_EXTERN(EditorLog, Verbose, All); ← REMOVE THE ;
This took a long while to discover, but it was it. Just the habit… be careful!
I don’t agree that library should be converted into ue4 module, since I found in default case, .lib does not have implement new and delete symbols, and they are ‘external’.
I resovled my similar issue by making sure all obj linking into exe file, have only one “new and delete” implemention.(like static symbols in .obj)
I encountered the same issue, and tried your solution wondering whether you removing the ‘;’ caused something else to happen, which fixed the error. In doing this my error was resolved, and I believe that this occurred due to me editing the module’s header file, where my log declarations are located. In summary if you edit your module’s header file and then build, the issue may be resolved.
This is most likely unrelated to the specific problem at hand, but I experienced an issue that had very similar symptoms. I’m building a plugin that loads an external library, and was getting LNK2005 errors on the new and delete operators, as well as some other random engine classes. This only occurred when building in the Shipping configuration.
For me, the problem ended up being that my plugin was using IMPLEMENT_PRIMARY_GAME_MODULE instead of IMPLEMENT_MODULE in the plugin’s main .cpp file. After switching to IMPLEMENT_MODULE and deleting the third macro parameter, everything was able to build successfully. (So yeah, the external library was a red herring.)
Just figured I should document this here, since this ended up being the thread I thought had the best chance of remedying the issue. Apologies for reviving this old thread, or if this is the wrong place to post such a thing. Cheers.
Well, it’s my turn to necro this thread to give you a massive thank you !
I also had random “already defined” stuff, such as GLiveCodingEngineDir, GTargetNameRegistration or GForeignEngineDir (putting this here for Google keywords :P) and I also had another module that was using IMPLEMENT_PRIMARY_GAME_MODULE instead of IMPLEMENT_MODULE !
I love you ! <3