Link to home
Start Free TrialLog in
Avatar of Escobar
Escobar

asked on

C# callback handler and type conversions

I have an API (I have control over it) written in C that accepts a callback target. During execution, the API will call back presenting an event code and a void * for the event context. Its the basic WndProc model (where the LPARAM will be cast'ed to the appropriate struct pointer), where depending on the event the context is converted to a pointer to a structure specific to that event.

In C#, the callback works, thats simple. What doesnt work is my efforts to on event X, convert the void * context argument to a C# structure.

How do I get the generic void * argument converted to a C# struct of type X for an event type of X, and a type of Y for event type Y?

I can of course take the brute force method of setting multiple callback targets, one for each event type, where the callback context is a known structure type, but thats less than ideal. Then again, its a small set of events, so maybe ill go that way. Regardless, this is something id like to understand going forward.

Im hoping this is a function of the language (C#) that I do net understand fully, so ive listed this as 'easy'.

Thanks
Avatar of Escobar
Escobar

ASKER

Code, if my question was not clear...

C API

extern "C"
{

//     Define the signature for a callback event handler
typedef unsigned int (CALLBACK  * EGLEVENTTARGETPROC)(unsigned int eventId, void * context);
}

EGLAPIEXPORT bool eglApplicationStart(EGLEVENTTARGETPROC eventTarget);

typedef struct tagEVENT_DUMMY
{
unsigned int test;
} EVENT_DUMMY, * PEVENT_DUMMY;

C# client

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct EventDummy
{
public uint test;
}

public delegate uint _EventHandler(uint eventId, [MarshalAs(UnmanagedType.SysInt)] IntPtr context);

public static uint eventHandler(uint eventId, IntPtr context)
{
  switch (eventId)
  {
    case 0: // Dummy EVent
    {
      // Now, how do I get the context in to a usable EventDummy structure?
    }
    break;
  }

  return (0);
}



Avatar of Escobar

ASKER

Code, if my question was not clear...

C API

extern "C"
{

//     Define the signature for a callback event handler
typedef unsigned int (CALLBACK  * EGLEVENTTARGETPROC)(unsigned int eventId, void * context);
}

EGLAPIEXPORT bool eglApplicationStart(EGLEVENTTARGETPROC eventTarget);

typedef struct tagEVENT_DUMMY
{
unsigned int test;
} EVENT_DUMMY, * PEVENT_DUMMY;

C# client

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct EventDummy
{
public uint test;
}

public delegate uint _EventHandler(uint eventId, [MarshalAs(UnmanagedType.SysInt)] IntPtr context);

public static uint eventHandler(uint eventId, IntPtr context)
{
  switch (eventId)
  {
    case 0: // Dummy EVent
    {
      // Now, how do I get the context in to a usable EventDummy structure?
    }
    break;
  }

  return (0);
}



ASKER CERTIFIED SOLUTION
Avatar of Nebulus_
Nebulus_

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Escobar

ASKER

Sometimes you just need to walk away for a few days. Your suggestion, while not technically correct, did help me to find the answer.

I understand the need for unsafe code marking, at the method and project level and that was already in place. At first, on reading your answer, I though that the problem may have been that I was not marking the structure definitions as unsafe. But the problem actually was that the structure in question, contains as a member, a managed type reference. The C api works with components that are also addressed by .NET classes. So the C API may return an object interface pointer that I can share with the .NET code. My mistake was listing the member of the struct as the .NET managed type and not as a generic intptr and performing a conversion later on in code. I was simply misreading the error as if it referred to my use of the structure itself, instead of in m use of n embedded managed type within an unmanaged or unsafe  structure.


Thanks very much