Error compiling S24 plugin
-
Hello,
I have worked for some weeks now on my plugin for the S24 version, but suddenly I got some compile errors, pointing to the platform toolset of visual studio. Has this happened to someone else as well? I am using VS2022, but the generator for S24 generated a VS2019 solution (or at least the projects are using the platform toolset of VS2019). Is this a known issue and does someone have a quick fix for this?
This is the error message I am getting:1>main.cpp 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(39,18): error C3668: "std::bad_cast::_Doraise": Die Methode mit dem Überschreibungsspezifizierer "override" hat keine Basisklassenmethoden überschrieben. (Quelldatei wird kompiliert ..\source\SomeClass.cpp) 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(40,9): error C3861: "_RAISE": Bezeichner wurde nicht gefunden. (Quelldatei wird kompiliert ..\source\SomeClass.cpp) 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(51,18): error C3668: "std::bad_typeid::_Doraise": Die Methode mit dem Überschreibungsspezifizierer "override" hat keine Basisklassenmethoden überschrieben. (Quelldatei wird kompiliert ..\source\SomeClass.cpp) 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\typeinfo(52,9): error C3861: "_RAISE": Bezeichner wurde nicht gefunden. (Quelldatei wird kompiliert ..\source\SomeClass.cpp)
The class SomeClass looks like this:
#pragma once #include <unordered_map> class DebugRenderer; class SomeClass { public: static SomeClass *GetInstance(); void RegisterDebugRenderer(int inCommandId, DebugRenderer *inRenderer); void UnregisterDebugRenderer(int inCommandId, DebugRenderer *inRenderer); DebugRenderer *FindDebugRenderer(int inCommandId); private: std::unordered_map<int, DebugRenderer*> mDebugRenderers; };
The class DebugRenderer registers itself in this singleton when being constructed and unregisters when its destructor is called.
Thank you for your time!
All the best,
CanEdit: I just tried out to remove the source files for SomeClass.h and SomeClass.cpp from the project and comment out every usage, then everything compiles successfully again. I added the files normally into the source directory and re-generated the project solution after that, so that it shows up inside visual studio and wrote the code normally inside VS. So I am not sure why this doesn't compile, any guidance would be greatly appreciated!
-
-
Hello @Cankar001,
Thank you for reaching out to us. You are doing here multiple things which are out of scope of support:
- Using VS 2022 for an S24 project.
- Using the std library in a Cinema 4D project.
- The std library itself is generally out of scope of support.
I have therefore moved your posting. I would also recommend only posting code and debug outputs that are in English here, as I am the only one in SDK who can read German.
The 'no std library' rule stems more from the fact that we want truly compiler agnostic code rather than it inherently not working with Cinema 4D. Deep in our API there of is of course some
std
code, but it is mostly the Tech team writing that code and not the majority of our developers who write code without using thestd
library at all. I would recommend the same for you. Because it could be that we provide replacements for parts of thestd
library (which shadow it then) or just use symbols which shadow entities instd
as we do not care.I would remove the
std::unordered_map<int, DebugRenderer*> mDebugRenderers;
, as this is the onlystd
code in that file. You can easily replace it withmaxon::HashMap
. This all reeks of 'you are mixing two versions ofstd
' for me, because that is the only way how C3668 instd
makes sense. Your errors also point to aC:\Program Files (x86)\Microsoft Visual Studio\2019\
while you claim to use VS 2022.If that does not help, I would follow the AI advice given below.
Cheers,
Ferdinand
AI advice:
The errors you're seeing are related to the
std::bad_cast
andstd::bad_typeid
exceptions in C++. The errors indicate that the methods_Doraise
with theoverride
specifier did not override any base class methods, and the identifier_RAISE
was not found.This could be due to a few reasons:
- You might be including the
<typeinfo>
header in a context where it's not supposed to be included, or it's being included indirectly through another header file. - There could be a conflict between different versions of the C++ standard library.
- There might be a problem with your Visual Studio installation.
Without seeing the actual code, it's hard to provide a specific solution. However, here are some general steps you can take to troubleshoot:
- Check your code for any unnecessary includes of
<typeinfo>
. - Make sure you're not mixing different versions of the C++ standard library.
- Try to rebuild your project.
- If none of the above work, consider reinstalling Visual Studio or repairing the installation.
Remember to always keep your software up-to-date to avoid such issues.
PS: Regarding the singleton/registration thing - You are also reinventing the wheel here the concepts of registries and published objects are very close to what you seem to want to do.
Finally, if you want a globally unique handler of something, you can also just use a
UniqueRef
to store it. Here is a small example of how you could do that (I wrote this 'blind' so it might not compile):// my_declr.h // Declare the globally unique render handler. UniqueRef realizes the singelton which stores a // map of <int, DebugRenderer>. We wrap DebugRenderer in a WeakRawPtr so that we do not // have to deal with possibly deleted objects. extern maxon::UniqueRef<maxon::HashMap<Int32, maxon::WeakRawPtr<DebugRenderer>> g_render_handler; // somefile.cpp/somefile.h // Somewhere in our code we then actually pull the object up. I am using here an // MAXON_INITIALIZATION macro so that the code runs when Cinema 4D is initialized. maxon::UniqueRef<maxon::HashMap<Int32, maxon::WeakRawPtr<DebugRenderer>> g_render_handler; MAXON_INITIALIZATION( // Boot []() -> maxon::Result<void> { iferr_scope; g_render_handler = maxon::UniqueRef< maxon::HashMap<Int32, maxon::WeakRawPtr<DebugRenderer>>::Create() iferr_return; return maxon::OK; }, // Teardown []() -> void { g_render_handler = nullptr; }); // Now we can use the g_render_handler in this manner: // Get a renderer for a given command ID. Result<DebugRenderer*> Get(Int32 id) { iferr_scope; // Try to get an entry ... const maxon::WeakRawPtr<DebugRenderer>* const item = g_render_handler->FindValue(id); if (!item) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION, "Could not find the renderer with id @1."_s, id); // Unpack the WeakRawPtr to make sure the object is still alive. DebugRenderer* const renderer = item->Get(); if (!renderer) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION, "The renderer with id @1 is no longer alive."_s, id); return renderer; } // Try to add a renderer to a given command ID slot. Result<void> Set(Int32 id, DebugRenderer* renderer) { iferr_scope; // Make sure the spot is still open. const maxon::WeakRawPtr<DebugRenderer>* const item = g_render_handler->FindValue(id); if (item) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION, "An renderer with id @1 already exists."_s, id); // Set the renderer. maxon::WeakRawPtr<DebugRenderer> weakPtr (renderer); g_render_handler->Insert(id, weakPtr) iferr_return; return maxon::OK; }
-
@ferdinand Thank you very much! I rewrote my code to your example provided, and now it works. I had another issue, where I tried to set the rendering config data right in the PluginStart method, but to that time no renderer interface seemed to be running already, so I moved this dependent code to another thread, that tries to retrieve the renderer instance from the hashmap and waits every time, when it failed to retrieve the instance and sets the data if it succeeded. This workflow seems to work very good now, the config data is always provided and now I have the ability to decide in the PluginStart() function already, which debug rendering features I want to enable
I only didn't understand, why the initial errors occurred, as I didn't include any typeinfo header directly (maybe caused by another std header then). But moving the code away from std seemed to help with that too.
-
Hey @Cankar001,
thank you for reaching out to us. It is great to hear that you found your solution! But I have troubles understanding all details of the rest of your question. However:
PluginStart
ist just an alias for the plugin messageC4DPL_INIT
.- A Cinema 4D instance has various stages in its startup and teardown sequence, as expressed by the plugin messages C4DPL_MESSAGES (see also: Plugin Messages).
- Through out the startup and teardown of Cinema 4D not all systems are available, as binaries/modules are loaded and unloaded and the systems associated with them are being pulled up and torn down.
- In the end it depends a bit on what you tried to do concretely, but generally speaking, it could very well be that something is not yet "up" when
C4DPL_INIT
is emitted. But in general, most modules, registries, etc. should be accessible at this point (plugins are loaded after the core and unloaded before the core).
To get here a more precise answer, I would recommend opening a new topic with concrete code.
Cheers,
Ferdinand