从WP8中的C ++代码调用C#方法

时间:2013-01-21 08:31:45

标签: windows-phone-8 c++-cx

我有兴趣从Windows Phone 8中的C ++代码调用C#方法。我已经学会了如何通过C ++代码中的委托声明将回调函数传递给C#中的C ++代码,但是我希望看看是否我可以做以下任何事情:

  • 直接从C ++代码调用某些方法。这将涉及以某种方式检查来自C ++的C#对象化妆,对我来说似乎不太可能,但我认为无论如何我都会问你们

  • 在C#代码中触发事件,然后可以通过C#方法处理

  • 使用调度程序在主UI线程中调用C#回调,以便回调可以修改UI元素

  • 使用调度程序触发C#代码中的事件,(基本上是上述两点的合并)

简而言之,我正在寻找尽可能多的C ++ - > C#通讯技巧,因为你们可以抛弃我,我想要学习它。 :)

2 个答案:

答案 0 :(得分:20)

通过获取C#代码中的对象来实现Windows RT接口,并传递对该对象的引用,可以通过一些设置来完成上述所有操作(如果我理解正确 - 不确定关于你想要用Dispatcher实例做什么 - 你可能想把Dispatcher包装在C#端。)

  1. 创建Windows运行时组件库。
  2. 在C ++ / CX标头中定义public interface class以供C#实现(C ++调用)(例如ICallback)。
  3. 在C ++ / CX标头中定义public ref class以供C ++实现(C#调用)(例如CppCxClass)。
  4. CppCxClass中添加一个传递并存储ICallback的方法。 (显示C ++全局变量是为了保证,我建议您查看一下,看看是否可以在代码库中找到更好的存储位置。)

    ICallback^ globalCallback;
    ...
    void CppCxClass::SetCallback(ICallback ^callback)
    {
        globalCallback = callback;
    }
    
  5. 在C#代码中引用WinRT库。

  6. C#代码:使用CppCxClass创建var cppObject = new CppCxClass()的实例。
  7. C#代码:创建一个实现ICallback的类(例如CSharpCallbackObject)。
  8. C#代码:将CSharpCallbackObject的实例传递给C ++。例如。 cppObject.SetCallback(new CSharpCallbackObject())
  9. 现在可以使用globalCallback->CallCsharp(L"Hello C#");调用C#。您应该能够延长ICallback和/或CppCxObject以执行其余任务。

答案 1 :(得分:16)

在经历了很多令人头疼的问题之后,我认为值得在这里发布最终版本

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);