Passing Function Pointer in C#

Tropicana55

I'm having trouble converting a C++ .dll function to C#.

The function is this:

    void funct(void*(*handler)(void*));

I think this means passing a pointer to function taking a void pointer and returning a void pointer, as explained here:

Passing Function Pointer.

What I'm trying to do is do the same thing in C#, but I have do idea how. I tried to use delegates, but I am both unsure how to and also if they can even do what I am trying to do.

Thanks for the help!

EDIT:

Here are the C++ functions for register_message_handler and message_handler:

void register_message_handler(void*(*handler)(void*));
void *message_handler(void *raw_message);

EDIT: xanatos has the exact explanation and conversion to C# below. Thanks a ton xanatos!

xanatos
void funct(void*(*handler)(void*));

is a function that accepts a pointer and returns a pointer.

In C# it would be:

IntPtr MyFunc(IntPtr ptr);

So you'll need a delegate like:

public IntPtr delegate MessageHandlerDelegate(IntPtr ptr);

[DllImport("mydll.dll")]
public static extern void register_message_handler(MessageHandlerDelegate del);

Note that P/Invoke (calling native methods) is one of the rare cases where Action<...> and Func<...> delegates don't work, and you have to build "specific" delegate.

BUT to call it, it's a little complex, because you must save a "copy" of the delegate so that if the C functions calls this method at any time, this copy is still "alive" and hasn't been GC (see for example https://stackoverflow.com/a/5465074/613130). The most common way to do it is to encapsulate everything in a class, and put the copy in a property/field of the class:

class MyClass
{
    public delegate IntPtr MessageHandlerDelegate(IntPtr ptr);

    [DllImport("mydll.dll")]
    public static extern void register_message_handler(MessageHandlerDelegate del);

    [DllImport("mydll.dll")] 
    public static extern IntPtr message_handler(IntPtr message);

    public MessageHandlerDelegate Del { get; set; }

    public void Register()
    {
        // Make a copy of the delegate
        Del = Handler;
        register_message_handler(Del);            
    }

    public IntPtr Handler(IntPtr ptr)
    {
        // I don't know what ptr is
        Console.WriteLine("Handled");
        return IntPtr.Zero; // Return something sensible
    }
}

Note that if you use IntPtr then you don't need the unsafe.

If you want to pass message_handler to register_message_handler the safest way is to

// Make a copy of the delegate
Del = message_handler;
register_message_handler(Del);

There is a possibility that you can do directly no there isn't, checked

register_message_handler(message_handler);

and that the CLR will solve this, BUT I'm not sure of this... I can't easily test it, and I wouldn't do it. (if you want to test it, add a GC.Collect() just after the register_message_handler. If after some time you receive a CallbackOnCollectedDelegate error then you know you can't do it :-) )

Mmmh... checked. You can't do the raw register_message_handler(message_handler), you have to use MyClass.

Be very aware of something: it's better to always specify the calling convention C-side and C#-side even in function pointers. C# uses stdcall, while C uses cdecl. In x86 mode you can get very awful silent crashes (in x64 there is a single calling convention)

void __stdcall register_message_handler(void* (__stdcall *handler)(void*));
void * __stdcall message_handler(void *raw_message);

and C# side

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr MessageHandlerDelegate(IntPtr ptr);

[DllImport("Win32Project1.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void register_message_handler(MessageHandlerDelegate del);

[DllImport("Win32Project1.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr message_handler(IntPtr message);

(or everywhere cdecl)

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

C - Passing pointer to function

From Dev

Passing a pointer to an array in a function in C

From Dev

C++ passing function pointer

From Dev

Passing a pointer (string) to a C function

From Dev

confusion in passing a pointer to function in C

From Dev

Passing pointer of an array to a function in C

From Dev

passing a pointer through a function c

From Dev

C++: Passing lambda pointer as a function pointer

From Dev

passing function pointer in c with a pointer argument

From Dev

Passing single pointer and double pointer to a function in c

From Dev

Boost C++. Passing a member function pointer with signature pointer to function

From Dev

Passing Array of Structs to a Function as a Pointer (C)

From Dev

passing a pointer of different type to a function (C)

From Dev

C++ crashing when passing pointer to function

From Dev

Passing pointer to an array into a function (C++)

From Dev

Passing a C function pointer to emscripten callback

From

passing function pointer to the C code using cgo

From Dev

Passing pointer to function that accepts reference in c++

From Dev

Passing a safe rust function pointer to C

From Dev

Passing in an element in an array as a pointer in a function in C

From Dev

Properly passing pointer from function C++

From Dev

C - Passing a pointer to an array to a function to print the array

From Dev

c struct passing itself as an argument into a pointer function

From Dev

c++ passing a pointer to a template function as template

From Dev

C problem with passing pointer to struct to function

From Dev

Passing a pointer to a char array as an argument to a function - C

From Dev

Passing pointer of a pointer in C

From Dev

Passing a pointer to a list, to a function

From Dev

Passing pointer to a function callback

Related Related

  1. 1

    C - Passing pointer to function

  2. 2

    Passing a pointer to an array in a function in C

  3. 3

    C++ passing function pointer

  4. 4

    Passing a pointer (string) to a C function

  5. 5

    confusion in passing a pointer to function in C

  6. 6

    Passing pointer of an array to a function in C

  7. 7

    passing a pointer through a function c

  8. 8

    C++: Passing lambda pointer as a function pointer

  9. 9

    passing function pointer in c with a pointer argument

  10. 10

    Passing single pointer and double pointer to a function in c

  11. 11

    Boost C++. Passing a member function pointer with signature pointer to function

  12. 12

    Passing Array of Structs to a Function as a Pointer (C)

  13. 13

    passing a pointer of different type to a function (C)

  14. 14

    C++ crashing when passing pointer to function

  15. 15

    Passing pointer to an array into a function (C++)

  16. 16

    Passing a C function pointer to emscripten callback

  17. 17

    passing function pointer to the C code using cgo

  18. 18

    Passing pointer to function that accepts reference in c++

  19. 19

    Passing a safe rust function pointer to C

  20. 20

    Passing in an element in an array as a pointer in a function in C

  21. 21

    Properly passing pointer from function C++

  22. 22

    C - Passing a pointer to an array to a function to print the array

  23. 23

    c struct passing itself as an argument into a pointer function

  24. 24

    c++ passing a pointer to a template function as template

  25. 25

    C problem with passing pointer to struct to function

  26. 26

    Passing a pointer to a char array as an argument to a function - C

  27. 27

    Passing pointer of a pointer in C

  28. 28

    Passing a pointer to a list, to a function

  29. 29

    Passing pointer to a function callback

HotTag

Archive