WP8:在WinRT组件(C++)中调用C#类库的解决方案

  在Windows Phone 8的开发过程中,特别是游戏开发过程中,WP8 SDK提供的工程模版Windows Phone XAML and Direct3D App是一个不错的选择。该工程采用C++和C#的混合编程模式,由一个C++编写的WinRT组件和一个C#项目组成,其中WinRT组件基于Direct3D编写,负责几乎所有的游戏逻辑,而C#则负责Windows Phone常规控件和页面逻辑,并提供一个DrawingSurface来处理游戏组件的事务。这种开发模式为游戏开发者节省了大批时间和精力。

  做过Windows Phone 7的开发者都知道,以前很多业务逻辑都是通过编写C#的类库进行封装并重复使用,但是到了Windows Phone 8,假如还想继续使用这类C#类库,并且需要在C++的代码中调用C#类库的接口时怎么办?

  直接在C++工程里引用C#类库是不行的,你会得到下面的错误:

  

  以下解决方案将彻底解决这个难题,以解决在D3D游戏逻辑中向OpenXLive提交分数为例子。

1.  首先默认你已经创建好了Windows Phone XAML and Direct3D App工程,并且在C#项目里面引用已有的C#类库,比如OpenXLive.dll

2.  WinRT组件中(C++)创建一个符合WinRT编程规范的接口ICallback,暴露给C#实现

创建一个ICallback.h文件:

namespace OpenXLiveSLDirect3DtTemplateComp
{
    namespace OpenXLiveHelper
    {
        // A callback interface for C# code to implement.
        public interface class ICallback
        {
        }
    }
}

 

3.  在WinRT组件中(C++)创建一个符合WinRT编程规范的类,用来传递和存储一个ICallback对象

创建XLiveDelegate.h文件和XLiveDelegate.cpp文件,在头文件中定义一个SetCallback方法:

#include "ICallback.h"

namespace OpenXLiveSLDirect3DtTemplateComp
{
    namespace OpenXLiveHelper
    {
        // A native class to pass and store an ICallback instance,
        // calling C# code via the ICallback object.
        public ref class XLiveDelegate sealed
        {
        public:
            XLiveDelegate();

            void SetCallback(ICallback^ callback);
            property static ICallback^ GlobalCallback;
        };
    }
}

其中,SetCallback将传递的ICallback对象保存在XLiveDelegate中:

void XLiveDelegate::SetCallback(ICallback^ callback)
{
    GlobalCallback = callback;
}

4.  在C#项目里面创建一个类实现WinRT组件暴露出来的接口ICallback

创建一个XLiveCallback.cs文件:

namespace OpenXLiveSLDirect3DtTemplate
{
    /// <summary>
    /// A callback class that implements the WinRT Component interface ICallback.
    /// All methods provided will be called throught the ICallback interface in native code.
    /// </summary>
    public class XLiveCallback : ICallback
    {
    }
}

5.  在C#项目中创建一个XLiveDelegate对象,并将一个XLiveCallback对象传递回C++代码

XLiveDelegate m_XLiveDelegate = new XLiveDelegate();
m_XLiveDelegate.SetCallback(new XLiveCallback());

6.  在WinRT组件中(C++)的ICallback接口中,提供一个提交分数的方法

public interface class ICallback
{
    void Leaderboard_Submit(Platform::String^ leaderboardKey, int score);
}

7.  XliveCallback类中实现这个方法,这个方法调用已有C#类库的方法

public class XLiveCallback : ICallback
{
    public void Leaderboard_Submit(string leaderboardKey, int score)
    {
        Leaderboard lb = new Leaderboard(XLiveGameManager.CurrentSession, leaderboardKey);
        lb.SubmitScoreCompleted += lb_SubmitScoreCompleted;
        lb.SubmitScore(score);
    }
}

其中Leaderboard类就是OpenXLive.dll的具体方法。

8.   Direct3D的游戏逻辑中,通过调用XLiveDelegate->GlobalCallback-> Leaderboard_Submit来间接调用C#类库的方法!

XLiveDelegate^ m_XLiveDelegate = ref new XLiveDelegate();
m_XLiveDelegate->GlobalCallback->Leaderboard_Submit("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 100);

 

 

posted @ 2013-03-20 15:55  zhxilin  阅读(2737)  评论(5编辑  收藏  举报