|
Hi,
I'm still working on the C# to C++ output module
for mcs. The changes to "Mint", and "Mono" are now complete (at least for
the version of Mono and Mint I have), and they are very minor. Both
Mint and Mono now can freely incorporate, create, call, and be called by C++
classes, and C++ statically compiled classes are now incorporated directly into
the Mono runtime as managed types. The overhead for a Jit to C++ call is
minor, and there is absolutely no overhead for the C++ to Jit
calls.
The mono to C++ bindings and integration are
accomplished through a change in the mono vtable layout. I made
mono's vtable extend backwards from the front of the vtable structure with -slot
vtable indexes, while c++'s vtable extends forwards after the mono vtable info
with normal positive indexes.
I also made a special platform dependent module
which extracts a classes vtable and method pointers is used to register the
C++'s methods as mono "internal" methods, and also give mono the layout of the
C++'s vtable so that mono can build the correct hybrid mono/c++ vtables when it
instantiates a c++ class. In the hybrid system, mono is
responsible for allocating and building all objects, both C++ and managed, but
as far as mono is concerned there is no difference between the two. I
think this should also work with practically any C++ compiler, though the user
will have to make a small interface to extract the method and vtable
pointers.
The C++ to mono bindings use macros which utilize
C's variable length argument list (...) format and function pointer semantics to
simply get the mono vtable function adress, and call it with the arguments to
the C++ version of the function. This compiles down into a very very nice
inline call in C++ that is really no different than calling a native C++ method,
except that the target of the call may be a trampolined Jit compiled method or
an interpreted method.
There was a bug in the mono trampoline code
(eax,edx,ecx were out of order), but since this code has been replaced in the
latest version, the problem is moot. Also, I had to actually make the Mint
system create real native calls for the vtable.. the version I had was just
placing mono "method" pointers in the vtable slots.
Finally, I converted both "mono" and "mint" into
statically linkable libraries with the expedient of changing their "main()"
functions to "mono()" and "mint()" respectively when MONO_LIB or MINT_LIB
was defined.
My test program works as follows...
The program initializes, and all global
constructors for the "Mono_Cpp::RegClass" classes add themselves to the
void (*mono_initialize_callback)() function pointer I added in order for
mono to call them back during mono's initialization.
The "main" method of my program is called. I
simply call create a 2 element array for mono's argv[] array with the name
of my internal metadata image file as the image to run (i.e. const char*
_argv[] = { argv[0], "internal:\\MyTest.exe" }; mono(2, _argv); )
Mono then begins as if it had been run from the command line with
"internal:\\MyTest.exe" as the image to run.
Mono then initializes, and after it loads up and
initializes "corlib.dll" it calls back my registration classes. Then the
linked list of Registration classes each register the c++ vtable, c++
method pointers for each C++ class, and for the entrypoint class, the metadata
binary image for the assembly. The
metadata binary image is simply a CIL compiled template of the assembly (in my
case "Test.exe") with all methods marked as "internal calls".
Then mono proceeds on normall.. searches for an
entry point.. finds it in my dummy metadata, calls it, executes my C++ main
funciton with an internal call, I then call System::Console::WriteLine() from
inside my test program, and I get "Hello World!". Tada.
------------------------------------------------------------
Right now I am finishing up the jitbindgen.c
program which will process a mono assembly and generate .h files with the C++ to
Jit bindings. I've done this by hand in my test programs, but I need to
automate to get the whole library. At that point, you will be able to code
by hand a C++ program that can utilize the CLR class runtime using
C++. After that, it's just back to finishing up the C# to C++
translator.
Ben
|
