1

I'm working on a C# code which uses a C++ dll
One function of the C++ dll takes a struct of 3 function pointers in parameter, I dont know how to manage it any tips or topics ?
I tried this but this doesnt work :

[StructLayout(LayoutKind.Sequential)]
public class DisplayCallBacks
{
    [MarshalAs(UnmanagedType.FunctionPtr)] initProgressBar ();                              
    [MarshalAs(UnmanagedType.FunctionPtr)] logMessage (int msgType, [MarshalAs(UnmanagedType.LPCWStr)] String str);
    [MarshalAs(UnmanagedType.FunctionPtr)] loadBar (int x, int n);                          
}

[DllImport("CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setDisplayCallbacks")]
internal static extern void SetDisplayCallbacks(DisplayCallBacks c);

C++ prototypes :

typedef struct displayCallBacks
{
    void (*initProgressBar)();                             
    void (*logMessage)(int msgType,  const wchar_t* str); 
    void (*loadBar)(int x, int n);                        
} displayCallBacks;

void setDisplayCallbacks(displayCallBacks c);
5
  • Can't tell without seeing the c++ prototype. You should us a structure instead of a class to make the same as c++. Commented Nov 6, 2020 at 14:16
  • I added the C++ prototypes Commented Nov 6, 2020 at 14:19
  • 1
    One issue is that none of your methods in DisplayCallbacks have any return types Commented Nov 6, 2020 at 14:21
  • You need to define the three types ProgressBar, logMessage, Bar and allocate the correct amount of memory for each type. The c++ code structure is 12 bytes since each pointer is 4 bytes. So you need 12 bytes for the structure in unmanaged memory as well as the unmanaged memory for the 3 objects. Commented Nov 6, 2020 at 14:26
  • What do you mean when you say define the three types ? declare the function ? Commented Nov 6, 2020 at 14:32

1 Answer 1

1

Use IntPtr as the type for the function pointers. Then you can declare a delegate. Here is an example from code I wrote:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void PrintLogDelegate(string msg);

PrintLogDelegate pld;
System.Runtime.InteropServices.GCHandle callbackPrintLog;
IntPtr ipCBPrintLog = IntPtr.Zero;

pld = new PrintLogDelegate(PrintLogFunc);
callbackPrintLog = System.Runtime.InteropServices.GCHandle.Alloc(pld);
ipCBPrintLog = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(pld);


void PrintLogFunc(string msg)
{

}

So ipCBPrintLog is what you pass to C++ as a callback.

Then in your Dispose you have to clean up: callbackPrintLog.Free();

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.