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. :)
When a program calls a function, the program control is transferred to the called function. A called function performs a defined task and when its return statement is executed or when its function-ending closing brace is reached, it returns the program control back to the main program.
The call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument. By default, C programming uses call by value to pass arguments.
Syntax to Call a Function If function returns a value, then we can store returned value in a variable of same data type. For Example. int sum = getSum(5, 7); Above statement will call a function named getSum and pass 5 and 7 as a parameter. It also stores the return value of getSum function in variable sum.
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).
public interface class
in a C++/CX header for the C# to implement (C++ to call) (e.g. ICallback
).public ref class
in a C++/CX header for the C++ to implement (C# to call) (e.g. CppCxClass
).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; }
Reference the WinRT library in your C# code.
CppCxClass
using var cppObject = new CppCxClass()
.ICallback
(e.g. CSharpCallbackObject
).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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With