Calling C ++ functions containing callbacks in C #

Hi everyone, I am trying to force myself to call this function C ++ in C #:

BOOL __stdcall CodecStart(int hRadio,void __stdcall (*CallbackFunc)(void *),void *CallbackTarget); 

this is from the WinRadio api found here http://www.winradio.com/home/g305_sdk.htm .

I found that other people were asking about calling this particular function on the network, and they had:

  public delegate void CallbackFunc( IntPtr p); [DllImport("WRG305API.dll")] public static extern bool CodecStart(int hRadio, CallbackFunc func, IntPtr CallbackTarget); 

but I can’t figure out how to implement this further.

any thoughts or recommendations on how to call it?

many thanks

+4
source share
3 answers

Here is a simple implementation that brings it all together.

 class WinRadioWrapper { public delegate void CallbackFunc( IntPtr pData ); [DllImport( "WRG305API.dll" )] public static extern bool CodecStart( int hRadio, CallbackFunc func, IntPtr CallbackTarget ); public bool CodecStartTest(int hRadio) { bool bStarted = CodecStart( hRadio, MyCallbackFunc, IntPtr.Zero ); return bStarted; } // Note: this method will be called from a different thread! static void MyCallbackFunc( IntPtr pData ) { // Sophisticated work goes here... } } 
  • Note that since MyCallbackFunc will execute on another thread, I decided to make it static . This way you will not want to access WinRadioWrapper data WinRadioWrapper .

  • For simplicity, I passed the IntPtr.Zero , but this may indicate any data that you would like to use in the callback.

    [Please ignore this point] Look at Marshal.StructureToPtr if you want to pass data to a callback, but also make sure to output the data you pass to make sure it is not a garbage collector (see GCHandle ).

EDIT:
With interesting svick words (thanks!), I understand that I was mixing the copied object with the pinned one.
So, to figure it out:

  • Marshal.StructureToPtr should be used if you want to copy an existing data structure and then pass it to the callback function.
  • If, on the other hand, you would like to use the existing data structure (for example, to change its contents), you should use GCHandle to lock it in memory and prevent its garbage collection. This, however, will add some overhead for GCHandle .
+4
source

A callback function is code that is called by the dll (in this case, you are importing) that performs some functions. You also need to learn how to work with delegates in C # . You can implement this code:

 public void MyCallback(IntPtr p) { //do something } 

and then your dll call will be like this:

 [DllImport("WRG305API.dll")] public static extern bool CodecStart(int hRadio, func, IntPtr CallbackTarget); 

If you need more recommendations, send the C ++ version of the code you want to convert, and we can help you with the C # version.

0
source

All you have to do is create a C # function that matches the signature of the declared delegate. Create a delegate, hold on to the link to that delegate so that it does not collect garbage and causes the dll import with the delegate as a callback.

so you have something like this:

 public void MyCallback(IntPtr P) { //do something } // somewhere else in your code var cb = new CallbackFunc(MyCallback); CodecStart(..., cb, ...); 
0
source

Source: https://habr.com/ru/post/1400898/


All Articles