2

I want unmanaged C++ code to call a C# function as a callback. I have a CLI/C++ class wrapping around the unmanaged code. An instance of this CLI/C++ class exists within the C#.

The C# code looks like the below text. I have a (delegate) function pointer to the callBack method. I have the CLI instance of CLI_class. I want to give it the function pointer somehow in the addValueChangedCallBack function.

public Setup(){
    tempFUNC myFuncObj = new tempFUNC(callBack)
    CLI_class c=new CLI_class();
    c.addValueChangedCallBack(myFuncObj)
}

public delegate void tempFUNC(float x);

void callBack(float x){
....
}

Then in the CLI code I want to do something like this:

void addValueChangedCallback(void (*ManipCallBack)(float)){
   unmanagedCPPCLASS.addValueChangedCallback(ManipCallBack)

}

How can I turn the function pointer into a C++ pointer (*)? Also, I cannot reference the C# project in the C++/CLI project because the C# class already references and uses the C++/CLI project. Will there be a dependency issue?

I have seen references on some sites to 'marshaling data' or using 'interop'. I don't understand how they work or what exactly they do from anything I have seen, are these what I should be using?

AAB
  • 674
  • 3
  • 14
  • 27
  • I'd try creating a wrapper C++ function of the correct signature that subsequently calls the C# function. You shouldn't need marshaling or interop when using C++/CLI, the whole point of that is having the compiler handle this using the language extensions. – millimoose Oct 24 '12 at 22:19
  • Declare the delegate type in the C++/CLI code so you don't have a dependency on the C# assembly. Make it public. Use Marshal.GetFunctionPointerForDelegate() to get a pointer you can pass to the native code. Don't forget to store the passed delegate object to keep it referenced. – Hans Passant Oct 24 '12 at 22:21
  • possible duplicate of [c++/cli pass (managed) delegate to unmanaged code](http://stackoverflow.com/questions/2972452/c-cli-pass-managed-delegate-to-unmanaged-code) – Hans Passant Oct 24 '12 at 22:24
  • Thanks for the feeback, How can I call the C# function from the C++ code? Currently my C# project references the CLI/C++ project, so I cannot reference the C# project from the CLI/C++ code. The dependency would be circular. Also, it is crucial that I use a method that already exists in the C# code (I need to interact C++ and C# GUI elements). – AAB Oct 24 '12 at 22:28
  • @Hans I don't think that it is an exact duplicate as there is a further requirement. The OP either needs to be told how to pass the C# delegate, or how to manage/wrap that from the managed C++. So he needs a little more elaboration/explanation than what's in your current linked answer? – slugster Oct 24 '12 at 22:51
  • Sure, covered by the comment. No "wrapping" required. – Hans Passant Oct 24 '12 at 22:54

1 Answers1

0

You can have both projects reference each other and use System.InteropServices.Runtime.Marshal.GetFunctionPointerForDelegate to get the function pointer.

But if I were you I'd make the C# class ComVisible and have the C++ code call the C# method directly though a COM interface. That way there's no need for a C++/CLI wrapper. Wrappers are always a pain, as you're experiencing. C++/CLI has its uses, but creating wrappers is not it.

user1610015
  • 6,561
  • 2
  • 15
  • 18
  • Thank you so much!! Do you you if there is a special way to make classes reference each other in Visual Studios? Or should they be referencing dlls? – AAB Oct 24 '12 at 23:49
  • The projects should reference each other. You can do this by right-clicking the project name in Solution Explorer and selecting **Add Reference...** – user1610015 Oct 25 '12 at 01:22
  • When I tried to do this before, Visual Studios said that it could not add a project reference to the project because it would cause a circular dependency. Is there some other way to do this? – AAB Oct 25 '12 at 01:57
  • Also the C++ code is a 3rd party graphics library and I don't have access to the source, so this is why I am using a complicated CLI layer. – AAB Oct 25 '12 at 02:12
  • Then declare the delegate type in the C++/CLI code so that the C++/CLI project doesn't have a dependency on the C# project, as @HansPassant said. – user1610015 Oct 25 '12 at 03:10
  • Ohh, so the delegate type is defined in the C++ but the actual function can still be in C# and you use marshal. Ok now I get what he meant, I am so dim. Thank you! – AAB Oct 25 '12 at 04:32