Calling C# method from C++ code in WP8
Asked Answered
C

2

14

I'm interested in calling a C# method from C++ code in Windows Phone 8. I have already learned how to pass a callback function to C++ code from C# via delegate declarations in my C++ code, but I am looking to see if I can do any of the following:

  • Call certain methods directly from the C++ code. This would involve somehow inspecting the C# object makeup from C++, and seems unlikely to me, but I thought I'd ask you all anyway

  • Trigger events in the C# code, which can then be handled by C# methods

  • Use a dispatcher to call C# callbacks in the Main UI thread so that the callbacks can modify UI elements

  • Use a dispatcher to trigger events in the C# code, (Essentially a merging of the above two points)

In short, I am looking for as many C++ -->C# communication tips as you guys can throw me, I want to learn it all. :)

Casper answered 21/1, 2013 at 8:31 Comment(0)
T
20

By getting an object in C# code to implement a Windows RT interface, and passing down a reference to this object, it is possible to do all of the above with a bit of set-up (if I understand correctly - not sure about exactly what you want to do with your Dispatcher examples - you might want to wrap the Dispatcher on the C# side).

  1. Create a Windows Runtime component library.
  2. Define a public interface class in a C++/CX header for the C# to implement (C++ to call) (e.g. ICallback).
  3. Define a public ref class in a C++/CX header for the C++ to implement (C# to call) (e.g. CppCxClass).
  4. Add a method in CppCxClass that passes and stores an ICallback. (A C++ global variable is shown for consiseness, I recommend you review this to see if you can find a better place to store this in your code-base).

    ICallback^ globalCallback;
    ...
    void CppCxClass::SetCallback(ICallback ^callback)
    {
        globalCallback = callback;
    }
    
  5. Reference the WinRT library in your C# code.

  6. C# code: create an instance of CppCxClass using var cppObject = new CppCxClass().
  7. C# code: create a class which implements ICallback (e.g. CSharpCallbackObject).
  8. C# code: pass an instance of CSharpCallbackObject down to C++. E.g. cppObject.SetCallback(new CSharpCallbackObject()).

You can now call C# with globalCallback->CallCsharp(L"Hello C#");. You should be able to extend either ICallback and/or CppCxObject to do the rest of your tasks.

Trentontrepan answered 21/1, 2013 at 9:45 Comment(6)
Great! This answers almost all of my questions! The last bit would be if l can use some kind of Dispatcher like I have in C# so that these callbacks can be invoked inside the main UI thread.Casper
Found a solution for the Dispatcher questions: #10579527Casper
Thanks a lot! I was looking for this kind of calling back technique and could not find it properly described anywhere elseLoutitia
Maybe I'm a C# noob but what's the namespace needed for ICallback ?Cyprinid
A complete implementation + walkthrough of this solution: developer.nokia.com/Community/Wiki/…Mcgehee
I don't get it. Where does the C# class instance come from, when the program is started in C++? Or how do you instantiate a C# class in C++?Lodestar
C
16

After a lot of headaches trying to figure out the required code, I think it's worth posting the final version here

C++/CX

//.h
[Windows::Foundation::Metadata::WebHostHidden]
public interface class ICallback
{
public:
    virtual void Exec( Platform::String ^Command, Platform::String ^Param);
};
//.cpp
ICallback ^CSCallback = nullptr;
void Direct3DInterop::SetCallback( ICallback ^Callback)
{
    CSCallback = Callback;
}
//...

if (CSCallback != nullptr)
    CSCallback->Exec( "Command", "Param" );

C#

public class CallbackImpl : ICallback
{
    public void Exec(String Command, String Param)
    {
        //Execute some C# code, if you call UI stuff you will need to call this too
        //Deployment.Current.Dispatcher.BeginInvoke(() => { 
        // //Lambda code
        //}
    }
}
//...
CallbackImpl CI = new CallbackImpl();
D3DComponent.SetCallback( CI);
Cyprinid answered 21/4, 2013 at 3:21 Comment(2)
It definitely is, cause then a guy like me comes along with the same problem and you save me loads of time. Thank you.Fishnet
It would be great if you can answer the related SO question @ #23872894Aarau

© 2022 - 2024 — McMap. All rights reserved.