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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM