Updated Playing with CPP VTABLE from Nim (markdown)

This commit is contained in:
andri lim 2016-01-30 11:34:12 +07:00
parent 059ca01e77
commit d279471635
1 changed files with 7 additions and 5 deletions

View File

@ -52,9 +52,9 @@ public:
### How Nim emulate C++ VTABLE ### How Nim emulate C++ VTABLE
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 problem. 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.
first, we will look at how Scintilla obtain pointer to ILexer instance from our dll. First, we will look at how Scintilla obtain pointer to ILexer instance from our dll.
```nimrod ```nimrod
type type
@ -72,9 +72,11 @@ proc GetLexerFactory(idx: int): LexerFactoryProc {.stdcall, exportc, dynlib.} =
result = nil result = nil
``` ```
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. 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. 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
```nimrod ```nimrod
proc Version(x: ptr ILexer): int {.stdcall.} = lvOriginal proc Version(x: ptr ILexer): int {.stdcall.} = lvOriginal
@ -112,7 +114,7 @@ See, VTABLE is only an array of pointers to functions, Nim can handle that easil
### How to call pure virtual functions from Nim ### How to call pure virtual functions from Nim
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? 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?
Armed with knowledge that C++ virtual functions tables is no more than an array of pointers. we can do something like this: Armed with knowledge that C++ virtual functions tables is no more than an array of pointers. we can do something like this: