3

I am trying to Marshall c call backs that are in a struct. I am pretty sure I have everything correct, but when using my C# example I don't get events, when using c++ I do get events.

Here is the C#

class Program
{
    [DllImport("Some.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int SetCallbacks(Callbacks callBack);


    static Callbacks Callback = new Callbacks { DataArrived = DataArrived, SendFailure = SendFailure };
    static void Main(string[] args)
    {
        SetCallbacks(Callback);

        Console.ReadLine();
    }

    static void DataArrived(uint id, IntPtr data)
    {

    }

    static void SendFailure(uint id, uint id2, IntPtr data)
    {

    }
}



[StructLayout(LayoutKind.Sequential)]
public struct Callbacks
{
    public DataArrived DataArrived;
    public SendFailure SendFailure;
}

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DataArrived(uint id,   IntPtr data);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SendFailure(uint id, uint id2, IntPtr ulpData);

This is from the C header file.

struct callBacks
{
    void (*dataArriveNotif) (unsigned int,    void*);
    void (*sendFailureNotif) (unsigned int, unsigned int, void*);
}

int SetCallbacks(callBacks callBacks);

Here is the working c++.

struct callBacks;
callbacks.dataArriveNotif = &dataArriveNotif;
callbacks.sendFailureNotif = &sendFailureNotif;
SetCallbacks(callBacks);
Will
  • 918
  • 5
  • 12
  • Use the debugger, enable unmanaged code debugging. Set breakpoints on the C code that makes the callback call (not visible) and the C# DataArrived method. – Hans Passant Mar 09 '11 at 19:55
  • I actually stepped into the SetCallbacks and the struct has all Null values, how did that happen? – Will Mar 09 '11 at 21:30
  • I don't know. Experiment with Marshal.StructureToPtr to see if the structure marshals correctly. – Hans Passant Mar 09 '11 at 21:48
  • @Will What is `Some.dll`, PInvoke library? If yes, where can I download it? – Mr. Blond Aug 06 '16 at 14:29

2 Answers2

1

Everything dealing with the delegate was actually correct. I simplified the senario a little bit in the example.

public static extern int SetCallbacks(Callbacks callBack); 

was actually

public static extern int SetCallbacks(String[] array, Callbacks callBack);

The string array had lots of trailing 0's at the end. Which made the callback struct all nulls. I gave up trying to marshal the string[] the correct way and just made it a Intptr and everything started working.

Will
  • 918
  • 5
  • 12
0

so very similar to this question asked yesterday...

PInvoke C#: Function takes pointer to function as argument

Community
  • 1
  • 1
Davide Piras
  • 43,984
  • 10
  • 98
  • 147
  • I actually have [UnmanagedFunctionPointer(CallingConvention.Cdecl)] attribute on the delegates. I also tried changing the struct to IntPtr's instead of the delegates and using Marshal.GetFunctionPointerForDelegate. It still doesn't work. – Will Mar 09 '11 at 19:04