Ing. Francesco Carsana wrote:
>> The recommended way is to declare the handlers as icalls in
>> managed code:
> 
> The problem is that I can't modify .NET assembly source code.
> I only know that assembly has this event:

You don't need to modify the original assembly. Implement the
wrapper in a new assembly.

> In my C++ wrapper class to this assembly, I have to find a way
> to pass a function pointer (or something else) to the assembly in
> order to manage that event. Is it possible?

No.

> Is there another way to do that?

No.

> Could someone please give me an example, please?


Untested. Implement this in its own assembly:

public class ConnectionEventWrapper
{
        [MethodImpl (MethodImplOptions.InternalCall)]
        public static extern void UnmanagedHandler (string n, bool c);

        public static void AttachEvent(Session source)
        {
                source.OnConnectionEvent +=
                        new ConnectionEventHandler (UnmanagedHandler);
        }

        public static void DetachEvent(Session source)
        {
                source.OnConnectionEvent -=
                        new ConnectionEventHandler (UnmanagedHandler);
        }
}


C++:

// this must be called once
mono_add_internal_call ("ConnectionEventWrapper::UnmanagedHandler",
        &icall_ConnectionEventWrapper_UnmanagedHandler);

void
icall_ConnectionEventWrapper_UnmanagedHandler (MonoString n,
        MonoBoolean c)
{
        // do something
}



Hooking the event:


void
ConnectionEventWrapper_AttachEvent (MonoObject* session)
{
        static MonoAssembly *assembly = NULL;
        static MonoClass *class = NULL;
        static MonoMethod *attach_event_method = NULL;

        MonoObject *exception;
        gpointer args[2];

        // load wrapper assembly
        if (!assembly) {
                MonoImageOpenStatus status;

                // "wrapper.dll" is the name of the assembly
                // implementing the wrapper.
                assembly = mono_assembly_open ("wrapper.dll", &status);

                g_assert (assembly);
        }

        // load class ConnectionEventWrapper
        if (!class) {
                class = mono_class_from_name (
                        mono_assembly_get_image (assembly),
                        "yournamespace", "ConnectionEventWrapper");

                g_assert (wrapper_class);
        }

        // load method ConnectionEventWrapper::AttachEvent
        if (!attach_event_method) {
                attach_event_method = mono_class_get_method_from_name (
                        class, "AttachEvent", 1);

                g_assert (attach_event_method);
        }


        // call AttachEvent(session);
        args [0] = session;
        mono_runtime_invoke (attach_event_method, NULL,
                args, &exception);

        if (exception) {
                // handle exception
        }
}


Robert

_______________________________________________
Mono-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to