Search code examples
c#pinvokemarshallingunmanagedmanaged

how to pass void * (pointing to double or int) from C to C#


I have general callback type in C:

typedef int(*OverrideFieldValueSetCB_t)(const char *Dialog, const char *FieldName, void *Value);

and callback:

OverrideFieldValueSetCB_t       gOverrideFieldValueSetCB;

and function I call in C-code to pass value to C# :

int DllGuiSetFieldValue(const char *Dialog, const char *FieldName, void *pValue)
{   
    return gOverrideFieldValueSetCB(Dialog, FieldName, pValue);
}

In C# code I set this kind of delegate:

private static int OverrideFieldValueSetCb(string dialogName, string fieldName, IntPtr value)
{
    ///...
}

In above I would like to marshal/cast value to int or double depending on fieldName.

Questions:

  1. Is IntPtr correct?
  2. If IntPtr is correct, how to cast/marshal it to double or int ?

Solution

  • "Pointing to double or int" is just asking for trouble.

    But if you're certain that's the way you want to go, have a look at the Marshal class - Marshal.ReadInt32 for int, and Marshal.PtrToStructure<double> for double. Make sure you don't mess the two up :)

    Of course, if you can use unsafe code, you don't need to use Marshal. Just do the cast as you would in C.

    Example:

    double val = 123.45d;
    double second;
    double third;
    
    unsafe
    {
      void* ptr = &val;
    
      second = *(double*)ptr;
      third = Marshal.PtrToStructure<double>(new IntPtr(&val));
    }
    
    second.Dump();