[Mono-dev] Creating Managed COM objects from C++ (on linux).

Tom Hindle tom_hindle at sil.org
Fri Dec 19 16:27:44 EST 2008


Hi,

I have implemented a COM object that allows creating of C# COM objects
from C++ on Linux. (a bit like mscoree for .NET I think..)

So I can do things like the following:

> TestComObject::IMyDotNetInterface *ptrMyDotNetInterface = NULL;
> 	if (S_OK != ::CoCreateInstance(TestComObject::CLSID_MyDotNetClass, NULL, CLSCTX_ALL, TestComObject::IID_IMyDotNetInterface, (void **)&ptrMyDotNetInterface))
> 	{
> 		fprintf(stderr, "CoCreateInstance Failed\n");
> 		return 1;
> 	}
> 	
> 	ptrMyDotNetInterface->ShowCOMDialog();

For a COM object defined like the following:

> using System;
> using System.Runtime.InteropServices;
> using System.Windows.Forms;
> 
> namespace TestComObject
> {
>     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
>     [Guid("03AD5D2D-2AFD-439f-8713-A4EC0705B4D9")]
>     public interface IMyDotNetInterface
>     {
>         void ShowCOMDialog();
>     }
>      
>     [ClassInterface(ClassInterfaceType.None)]
>     [Guid("0490E147-F2D2-4909-A4B8-3533D2F264D0")]
>     public  class MyDotNetClass : IMyDotNetInterface
>     {
>         public MyDotNetClass()
>         {}
>         public void ShowCOMDialog()
>         {		
> 			Console.WriteLine("Hello World");
> 			System.Windows.Forms.MessageBox.Show("Hello");
>         }
>     }
> }
> 

However in order to do this I had to convert from a MonoObject to a COM interface pointer.
The only way I could work out how to do this was by using some internal mono functions. (removing static from mono src files ect.)

> 	comClassInstance = mono_object_new (m_domain, comClass);	
> 	
> 	if (comClassInstance == NULL)
> 	{
> 		fprintf(stderr, "Failed to create instance of %s.%s from assembly %s\n", classNamespace.c_str(), className.c_str(), assemblyName.c_str());
> 		return 1;
> 	}
> 	
> 	////
> 	// Get object callable from C++
> 	////
> 		
> 	mono_init_com_types(); // Internal mono function
> 	
> 	void *pCCW = (void*)ves_icall_System_Runtime_InteropServices_Marshal_GetIUnknownForObjectInternal(comClassInstance); // Internal mono function
> 	
> 	cominterop_ccw_queryinterface(pCCW,(guint8*)&riid, (void**)ppvObject); // Internal mono function

I think I could replace ves_icall_System_Runtime_InteropServices_Marshal_GetIUnknownForObjectInternal with mono_lookup_internal_calls
but I don't know how to get around the need to call mono_init_com_types() and cominterop_ccw_queryinterface().

Any ideas anyone?

Thanks
Tom




More information about the Mono-devel-list mailing list