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
 
 
 
 
 

Reply via email to