In this case, I think it depends on std::runtime_error. For the client to use this class it must use the definition as provided on the client side, not the DLL side. For this to succeed the client compiler should be exactly the same version as the DLL compiler.
And apart from the fact that class definitions are not portable across module boundaries, there is also the memory ownership to consider.
If you derive from a class that has an internal variable like a std::string, it would be a disaster waiting to happen. If the dll would use a different runtime from the application in which another class derives from it, the following could happen:
- Base initializes the string with a text value.
- Derived would try to change the string.
- It would try to release the heap memory of the string.
This is not limited to strings of course. It was just an example. Any scenario where 1 runtime allocates something and another deallocates it will result in a crash.
The heap memory is owned by the runtime that is used by the base class. Thr runtime of the derived class tries to release it -> instant crash. You are at the mercy of the dll provider in order to give you a dll that is compiled with the same C++ compiler, and uses the same runtime. This is a maintenance nightmare.
DLL class interfaces are without a doubt the worst idea ever.
The only 2 exemptions are:
- you use DCOM (or pure abstract classes, which is the same idea)
- you are in control of the entire code tree. For example the dll and the exe are built in the same solution.
In all other cases, DLL class interfaces are support nightmares, and disasters waiting to happen.
I think this thread
can possibly suggest you a solution.
Feel free to ignore C4275 if you compile everything with the same compiler and use /MD
so all modules share the same runtime.