[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