First I will try to define the question in one sentence, then I will go into details.
Question: Is there a way to call non virtual functions on class instances created in a DLL, where the implementation is not known at compile and link time, since hidden in a DLL?
Background: I have a system in place, where I compile a piece of code (a module) into a DLL and load this DLL in my application on-demand when GetModule(Name) is called.
On windows, loading is done with LoadLibrary
void* DynamicLibraryLoaderWin::LoadDynamicLibrary(const std::wstring& file_path)
{
auto* library_handle = LoadLibraryW(file_path.c_str());
if (!library_handle)
{
const auto error = GetLastError();
assert(false);
}
return library_handle;
}
After I get the handle, I can create a module instance by calling an exported C function in the DLL that will return me an instance of a my desired module class.
Example Module:
class ModuleExample : public IModule
{
public:
virtual std::string* GetString() const;
};
Now, if I want to call GetString() on ModuleExample, I have to make the function virtual. If I don't do that, I will end up with a linker error since there is code somewhere in my application that executes GetString() and the linker cannot find the implementation -> since hidden in a DLL that is not yet present. If I make the function virtual, the linker does not complain since everything goes over the V-table, which is known to the compiler and linker.
Now we can argue that making all functions virtual is the solution, but there is a small overhead for virtual functions that is not trivial for performance critical code. Therefore, I'm searching for a solution to not make all functions virtual.
Another small negative effect is that I cannot make ModuleExample final, since it tries devirtualisation on virtual functions, and the linker complains again.
Maybe interesting: I'm using CMake to setup my modules and applications, and all modules are defined as libraries with the property INTERFACE, and also linked with INTERFACE. I heard something about MODULE, but did not give it a try yet.