[Mono-list] Mono Embedding: manage events
Robert Jordan
robertj at gmx.net
Wed Apr 2 05:53:04 EDT 2008
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
More information about the Mono-list
mailing list