前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.3

20.10. BREW エクステンションにおける AEEApplet 構造体参照の問題

[Caution] 注意

BREW エクステンション内で呼び出し元アプリの AEEApplet 構造体から IShell インターフェースや IDisplay インターフェースを参照しようとしたときに端末がリセットする問題は、 SophiaFramework UNIVERSE 5.1.10 で以下に述べる方法により解決されています。

20.10.1. 問題の概要

SophiaFramework UNIVERSE(5.1.9 以前)で開発した BREW アプリから BREW エクステンションから呼び出したときに、 その BREW エクステンションが呼び出し元 BREW アプリの AEEApplet 構造体から IShell インターフェースや IDisplay インターフェースを参照しようとすると、 端末がリセットすることが確認されています。

この問題は、BREW SDK で開発した BREW アプリと SophiaFramework UNIVERSE(5.1.9 以前)で開発した BREW アプリについて、 BREW API GETAPPINSTANCE 関数を呼び出して取得できる AEEApplet 構造体のレイアウトが異なることに起因します。

標準的な BREW エクステンションでは、 暗黙的に呼び出し元 BREW アプリの AEEApplet 構造体を直接参照することはなく、 必要な情報は引数を経由して受け取るので問題は発生しません。

ごく稀なケースとして、ある BREW エクステンションの実装では、 BREW API GETAPPINSTANCE 関数を呼び出して、 BREW エクステンションを呼び出した BREW アプリの AEEApplet 構造体から BREW API IShell インターフェースや BREW API IDisplay インターフェースを参照しようとします。 (※ 本来であれば、これらは引数として渡される、もしくは、 エクステンション内で生成すべきインターフェースです。)

SophiaFramework UNIVERSE(5.1.9 以前)で開発された BREW アプリの場合、 BREW API GETAPPINSTANCE 関数を呼び出して取得できる AEEApplet 構造体には、 それらが含まれませんので、端末がリセットする可能性があります。

[Caution] 解決方法

この問題を解決するには、 BREW エクステンションから呼び出し元 BREW アプリの AEEApplet 構造体を参照することを止めるのが先決と考えられます。

SophiaFramework UNIVERSE 側で解決するには、 BREW API GETAPPINSTANCE 関数を呼び出して取得できる、 SophiaFramework UNIVERSE の BREW アプリの AEEApplet 構造体に BREW API IShell インターフェースや BREW API IDisplay インターフェースなどの要素を持たせる必要があります。

この修正は、SophiaFramework UNIVERSE 5.1.10 で行われました。 BREW エクステンション側で解決できない場合は、 5.1.10 以降のSophiaFramework UNIVERSEを利用して BREW アプリを開発してください。

20.10.2. SophiaFramework UNIVERSE 側での解決方法

標準 BREW の AEEApplet 構造体は、 AEEAppGen.h で以下のように定義されています。

例 20.35. 標準 BREW で定義される AEEApplet 構造体

// 標準 BREW で定義される AEEApplet 構造体
/*-------------------------------------------------------------------
      Type Declarations
-------------------------------------------------------------------*/
//Structure to hold Applet infprmation
typedef struct _AEEApplet AEEApplet;

struct _AEEApplet
{
    // 
    // NOTE:  These 3 fields must be declared in this order!
    // 
    DECLARE_VTBL(IApplet)
    AEECLSID       clsID;
   
    uint32         m_nRefs;	  // Applet reference counter
    IShell    *    m_pIShell;	  // pointer to IShell   
    IModule   *    m_pIModule;	  // pointer to IModule  
    IDisplay  *    m_pIDisplay;   // pointer to IDisplay 

    //Pointer to Handle Event Function
    AEEHANDLER     pAppHandleEvent;

    // Pointer to FreeAppData function. This will be invoked when the     
    // reference count of the App goes to zero. This function is supplied 
    // by the app developer.                                              
    // NOTE: Apps should NOT directly call their FreeAppData function.    
    PFNFREEAPPDATA pFreeAppData;
};

この定義を読む限りでは、

    // NOTE:  These 3 fields must be declared in this order!

の注意書きにあるように、

    DECLARE_VTBL(IApplet)
    AEECLSID       clsID;
   
    uint32         m_nRefs;	  // Applet reference counter

の 3 つのフィールドが先頭からこの順番で並んでいることだけが、 AEEApplet 構造体としての必要条件と考えられます。

BREW アプリの AEEApplet 構造体は、 BREW エクステンションの中で BREW API GETAPPINSTANCE 関数の戻り値を 以下のように (AEEApplet*) でキャストすることより参照できます。

   IShell*   shell   = ((AEEApplet*)GETAPPINSTANCE())->m_pIShell;
   IDisplay* display = ((AEEApplet*)GETAPPINSTANCE())->m_pIDisplay;

SophiaFramework UNIVERSE(5.1.9 以前)では、 AEEApplet 構造体に相当するものは SFCApplet クラス内で以下のように定義されています。

例 20.36. SophiaFramework UNIVERSE 5.1.9 以前の SFCApplet クラスの定義(AEEApplet 構造体のレイアウト)

// SophiaFramework UNIVERSE 5.1.9 以前の SFCApplet クラスの定義(AEEApplet 構造体のレイアウト)
class SFCApplet {

                ...

    private:
                DECLARE_VTBL(IApplet)
                AEECLSID                  _id;
                UInt32                    _telomere;
                SFBShellSmp               _shell;
                SFBModuleSmp              _module;
                SFXGraphics               _graphics;

                ...
}

最初の 3 つ目までのフィールドまでは標準 BREW と同じですが、 4 つ目以降は異なります。

そのため、BREW エクステンション内で呼び出し元 BREW アプリの AEEApplet 構造体から BREW API IShell インターフェースや BREW API IDisplay インターフェースを参照しようとすると、 SFCApplet クラスではそれらが定義されていないため、端末がリセットします。

5.1.10 以降の SophiaFramework UNIVERSE では、 以下のように SFCApplet クラスを 標準 BREW の AEEApplet 構造体と互換性を維持するように変更されているので、 上記の端末リセットの問題は発生しません。

例 20.37. SophiaFramework UNIVERSE 5.1.10 以降の SFCApplet クラスの定義(AEEApplet 構造体のレイアウト)

// SophiaFramework UNIVERSE 5.1.10 以降の SFCApplet クラスの定義(AEEApplet 構造体のレイアウト)
class SFCApplet {

                ...

    private:
                DECLARE_VTBL(IApplet)
                AEECLSID                  _id;
                UInt32                    _telomere;
                IShell*                   m_pIShell;
                IModule*                  m_pIModule;
                IDisplay*                 m_pIDisplay;
                SFBShellSmp               _shell;
                SFBModuleSmp              _module;
                SFXGraphics               _graphics;

                ...
}