This method have been tested to be interoperable between MS-VCC and GCC(MINGW) on Windows, and should be compatible with LLVM-clang too. But for other C++ compiler, there is no guarantee this method will work. So use it with cautions. Generally this is really unsafe assumption about how C++ compiler works. Don't rely on this explanation if you are not sure what really happened under the hood. Better wrap the virtual functions call in an extern "C" function and call that from Nim if you want to be sure the compiler generate correct virtual functions call.
Imagine you are trying to communicate with a C++ app from Nim, and the C++ interface only provide a bunch of pure virtual functions classes, and a pointer to the class instance. Only a few `extern "C"` functions to initialize the communication, all other communications must be done via that pointer. What will you do?
notepad++ plugin is a normal dll with normal interface. Standard notepad++ plugin requires standard cdecl calling convention for it's binary interface, not a big problem, Nim ffi can handle that perfectly. But things get more interesting when we want to make an external lexer for notepad++ editor engine: Scintilla.
Although that external lexer we want to create must also be reside in the same dll with our notepad++ plugin, it has different calling convention, scintilla requires stdcall calling convention for all functions it needed. Again, this is not a problem for Nim, just use {.stdcall.} pragma. But there is another requirement for notepad++ plugin: all exported function name must not be decorated ala normal stdcall, so we need to activate `-Wl,--kill-at` switch when compile the plugin project, and the C/C++ compiler will handle that.
OK, so far no C++ features we already met. But wait, that's not the real interface to Scintilla, it's only entry point for a more complicated interface.
ILexer is the real interface to external lexer that we must provide from our dll. IDocument is the interface we need to communicate with Scintilla. Both of them are pure virtual functions classes. Nim not support C++ classes nor virtual functions, really? yes, no C++ equivalent class in Nim, no virtual functions in Nim. That's why this wiki is written, to overcome this kind of problem.
Scintilla will call our GetLexerFactory, and the factory is a function returning a pointer to ILexer. You can see how we can simulate ILexer from Nim and then exporting correct instance to be called by Scintilla.
From the above snippet, we can see that C++ virtual functions is implemented via a pointer to array of pointers. That is the very basic concept of how C++ compilers implement virtual functions classes.
Now let's write Nim code that can emulate this behavior
Now, we already know how to provide ILexer implementation from our dll, but what about IDocument? IDocument implementation is provided by Scintilla, how can we call IDocument member functions from Nim?
Again, we can see how actually C++ compilers translate `->` operator when calling virtual functions, it will use the right index to the vtable and call the function via pointer, that what we also do in Nim, cast the typeless pointer to proc pointer and call it, don't forget that the first argument is also a pointer to the class instance.
That's it, not too difficult heh? It's not too difficult because we are not dealing with C++ name mangling here, only dealing with pointers and calling convention, Nim can handle that perfectly, although a bit verbose compared to C++ style.
What about C++ ordinary [member] functions, constructor, and destructor?, well that's another story, C++ name mangling can be a nightmare if you try to solve that in Nim, because every C++ compiler have their own flavor/style of name mangling, but if you know the exact formula of C++ name mangling, please write another wiki!