SophiaFramework UNIVERSE 5.3 |
BREW インターフェースには、以下の 3 種類があります。
上に挙げたそれぞれの BREW インターフェースの C++ ラッパークラスの実装で異なるのは、 インスタンスの生成方法、つまり NewInstance 関数の部分だけです。
具体的には、以下の通りです。
IHash インターフェースのラッパークラス SFBHash の作成方法について説明します。
IHash インターフェース | |
---|---|
IHash インターフェースは、ISHELL_CreateInstance 関数を使用してそのインスタンスを生成するインターフェースです。 |
ラッパークラスの作成は、ラッパークラスの定義とそのメンバー関数の実装からなります。
IHash インターフェースのラッパークラス SFBHash を定義します。
IHash インターフェースは IBase インターフェースを継承するので、 SFBHash クラスは IBase インターフェースのラッパークラス SFBBase クラスを継承します。
IHash インターフェースにない SFBHash::NewInstance 関数を追加します。 この関数は スマートポインタで管理される SFBHash クラスのインスタンスを生成するための関数です。
次に、IHash インターフェースの IHASH_GetResult / IHASH_Restart / IHASH_SetKey / IHASH_Update 関数について、 SFBHash::GetResult、SFBHash::Restart、 SFBHash::SetKey、SFBHash::Update をラッパークラスのメンバ関数として定義します。
下記の例のように、 いくつかのメンバ関数では、 SFXBuffer などの SophiaFramework UNIVERSE 独自のクラスを引数として渡せるように拡張しています。
例 21.11. SFBHash ラッパークラスの定義
// SFBHash ラッパークラスの定義 #include <SFBWrapper/SFBEnvironment.h.hpp> #include <AEESecurity.h> #include <SFBWrapper/SFBBase.h.hpp> // SFXBuffer クラスの便利な型を自動生成するマクロ SFMTYPEDEFCLASS(SFXBuffer) // SFBHash ラッパークラスの便利な型を自動生成するマクロ SFMTYPEDEFWRAPPER(SFBHash) class SFBHash : public SFBBase { // SFBHash は SFBBase を継承する // ラッパークラスのインスタンスのコピーを禁止するマクロ SFMSEALWRAPPER(SFBHash) // ラッパークラスの継承関係を記述するマクロ SFMWRAPPERINSTANTIATEONE(SFBHash, SFBBase) public: static SFBHashSmp NewInstance (AEECLSID id, SFCErrorPtr exception = null); SFCError GetResult (VoidPtr data, SInt32Ptr size); Void Restart (Void); SFCError SetKey (VoidConstPtr key, SInt32 keySize); Void Update (VoidPtr data, SInt32 dataLength); // SophiaFramework UNIVERSE の SFXBuffer クラスを引数として渡せるようにしたメンバ関数 SFCError GetResult (SFXBufferPtr data); SFCError SetKey (SFXBufferConstRef key); Void Update (SFXBufferPtr data); }; // BREW インターフェースとラッパークラスの型変換の関数を宣言するマクロ SFMWRAPPERINTERFACECASTDECLARE(SFBHash, IHash)
IBase インターフェースの関数 | |
---|---|
IHASH_AddRef / IHASH_Release 関数は IBASE_AddRef / IBASE_Release 関数を継承する関数です。 これらの関数については IHash インターフェースが継承する IBase インターフェースの ラッパークラス SFBBase 内で既に実装されているので、 SFBHash クラスで定義する必要はありません。 なお、SophiaFramework UNIVERSE ではスマートポインタを利用しているので、 インスタンスの参照カウントに関わる IBASE_AddRef / IBASE_Release 関数に対応するメンバ関数は private 関数として実装し、 この関数にアクセスできない設計になっています。 |
SFMTYPEDEFCLASS マクロ | |
---|---|
SFMTYPEDEFCLASS は、 引数に指定したクラスに関する便利なユーザー定義型を自動生成するマクロです。 |
SFMTYPEDEFWRAPPER マクロ | |
---|---|
SFMTYPEDEFWRAPPER は、 引数に指定したラッパークラスに関する便利なユーザー定義型を自動生成するマクロです。 SFBHashSmp 型は SFMTYPEDEFWRAPPER(SFBHash) マクロで定義されます。 |
SFMSEALWRAPPER マクロ | |
---|---|
SFMSEALWRAPPER はラッパークラスのインスタンスのコピーを禁止するマクロです。 ラッパークラスのインスタンスはコピーしてはいけません。 |
SFMWRAPPERINSTANTIATEONE マクロ | |
---|---|
SFMWRAPPERINSTANTIATEONE はラッパークラスの継承関係を記述するマクロです。 IBase インターフェースからの継承関係をこのマクロを使用して記述します。 IHash インターフェースは IBase インターフェースを継承しますので、IBase インターフェースのラッパークラスを SFBBase クラスとすると、 IHash インターフェースのラッパークラスである SFBHash クラスは SFBBase クラスを継承するので SFMWRAPPERINSTANTIATEONE(SFBHash, SFBBase) とマクロ宣言します。 SFBBase クラスでは、継承関係で最上位に位置するので SFMWRAPPERINSTANTIATEZERO マクロを使用してこの部分は SFMWRAPPERINSTANTIATEZERO(SFBBase) とマクロ宣言します。 A、B、C の 3 つのラッパークラスがあり、B は A、C は B をそれぞれ継承する場合は、SFMWRAPPERINSTANTIATETWO マクロを使用して SFMWRAPPERINSTANTIATETWO(C, B, A) とマクロ宣言します。 A、B、C、D の 4 つのラッパークラスの場合は、SFMWRAPPERINSTANTIATETHREE(D, C, B, A) とマクロ宣言します。 RealView Compilation Tools for BREW 1.2 コンパイラの不具合を回避するためのマクロです。 RealView Compilation Tools for BREW 1.2 以外のコンパイラでは無視されます。 |
SFBHash::NewInstance 関数 は SFBBase::FactoryByCreate 関数を使用して次のように実装します。
例 21.12. SFBHash::NewInstance 関数の実装方法
// SFBHash::NewInstance 関数の実装 #include <SFBWrapper/SFBHash.h.hpp> /*public static */SFBHashSmp SFBHash::NewInstance(AEECLSID id, SFCErrorPtr exception) { // FactoryByCreate() を使用して NewInstance() を実装する // static_pointer_cast マクロでダウンキャストする return static_pointer_cast<SFBHash>(FactoryByCreate(id, exception)); }// SFBHash::NewInstance //
SFBHashSmp スマートポインタ | |
---|---|
SFBHashSmp は SFBHash のインスタンスを管理するスマートポインタの型です。 この型は SFMTYPEDEFWRAPPER(SFBHash) マクロで定義されています。 |
SFBHash クラスのメンバ関数を実装します。
SFBHash::SetKey 関数を実装について、 BREW 標準のメンバ関数の実装と SophiaFramework UNIVERSE の型を引数にできるメンバ関数の実装を以下に記します。
例 21.13. IHash インターフェースの IHASH_SetKey 関数をラップする SFBHash::SetKey 関数の実装 1
// SFBHash::SetKey 関数の実装 1 #include <SFBWrapper/SFBEnvironment.h.hpp> // インライン関数でラップすることで実行時の速度低下を回避する /*public */inline SFCError SFBHash::SetKey(VoidConstPtr key, SInt32 keySize) { // BREW インターフェースの IHASH_SetKey 関数呼び出して実行する return IHASH_SetKey(interface_cast(this), static_cast<ByteConstPtr>(key), keySize); }// SFBHash::SetKey //
例 21.14. IHash インターフェースの IHASH_SetKey 関数をラップする SFBHash::SetKey 関数の実装 2 (SophiaFramework 機能拡張メンバ関数)
// SFBHash::SetKey 関数の実装 2 #include <SFBWrapper/SFBEnvironment.h.hpp> #include <SFXBuffer/SFXBuffer.h.hpp> // インライン関数でラップすることで実行時の速度低下を回避する /*public */inline SFCError SFBHash::SetKey(SFXBufferConstRef key) { // BREW インターフェースの IHASH_SetKey 関数を呼び出して実行する // SophiaFramework UNIVERSE の SFXBuffer クラスを引数にできるように機能拡張 return IHASH_SetKey(interface_cast(this), static_cast<ByteConstPtr>(key.GetBuffer()), key.GetSize()); }}// SFBHash::SetKey //
例 21.15. IHash インターフェースの IHASH_GetResult 関数をラップする SFBHash::GetResult 関数の実装 (SophiaFramework 機能拡張メンバ関数)
// SFBHash::GetResult 関数の実装(この関数はインライン関数として実装できない) #include <SFBWrapper/SFBHash.h.hpp> // SophiaFramework UNIVERSE の SFXBuffer クラスを引数にできるように機能拡張 /*public */SFCError SFBHash::GetResult(SFXBufferPtr data) { if (data == null) { return SFERR_INVALID_PARAM; } SIntN size(data->GetSize()); // BREW インターフェースの IHASH_GetResult 関数を呼び出して実行する SFCError result(IHASH_GetResult(interface_cast(this), static_cast<BytePtr>(data->GetBuffer()), &size)); if (result == SFERR_NO_ERROR) { if (static_cast<SInt32>(data->GetSize()) > size) { result = data->SetSize(size); } } else { if (result == AEE_HASH_MORE_DATA) { if (size < 0) { return SFERR_FAILED; } if ((result = data->SetSize(size)) == SFERR_NO_ERROR) { // BREW インターフェースの IHASH_GetResult 関数を呼び出して実行する result = IHASH_GetResult(interface_cast(this), static_cast<BytePtr>(data->GetBuffer()), &size); } } } return result; }// SFBHash::GetResult //
参考までに SFBHash クラスの全メンバ関数の実装コードを以下に記します。
例 21.16. 参考 1 : インライン 関数を使った SFBHash クラスのメンバ関数の実装
// インライン 関数による SFBHash クラスのメンバ関数の実装
#include <SFBWrapper/SFBEnvironment.h.hpp>
#include <SFXBuffer/SFXBuffer.h.hpp>
/*public */inline SFCError SFBHash::GetResult(VoidPtr data, SInt32Ptr size)
{
return IHASH_GetResult(interface_cast(this), static_cast<BytePtr>(data), reinterpret_cast<SIntNPtr>(size));
}// SFBHash::GetResult //
/*public */inline Void SFBHash::Restart(Void)
{
IHASH_Restart(interface_cast(this));
return;
}// SFBHash::Restart //
/*public */inline SFCError SFBHash::SetKey(VoidConstPtr key, SInt32 keySize)
{
return IHASH_SetKey(interface_cast(this), static_cast<ByteConstPtr>(key), keySize);
}// SFBHash::SetKey //
/*public */inline Void SFBHash::Update(VoidPtr data, SInt32 dataLength)
{
IHASH_Update(interface_cast(this), static_cast<BytePtr>(data), dataLength);
return;
}// SFBHash::Update //
/*public */inline SFCError SFBHash::SetKey(SFXBufferConstRef key)
{
return IHASH_SetKey(interface_cast(this), static_cast<ByteConstPtr>(key.GetBuffer()), key.GetSize());
}// SFBHash::SetKey //
SFMWRAPPERINTERFACECASTIMPLEMENT(SFBHash, IHash)
例 21.17. 参考 2 : インライン 関数で実装できない SFBHash クラスのメンバ関数の実装
// インライン 関数を使わない SFBHash クラスのメンバ関数の実装
#include <SFBWrapper/SFBHash.h.hpp>
/*public static */SFBHashSmp SFBHash::NewInstance(AEECLSID id, SFCErrorPtr exception)
{
return static_pointer_cast<SFBHash>(FactoryByCreate(id, exception));
}// SFBHash::NewInstance //
/*public */SFCError SFBHash::GetResult(SFXBufferPtr data)
{
if (data == null) {
return SFERR_INVALID_PARAM;
}
SIntN size(data->GetSize());
SFCError result(IHASH_GetResult(interface_cast(this), static_cast<BytePtr>(data->GetBuffer()), &size));
if (result == SFERR_NO_ERROR) {
if (static_cast<SInt32>(data->GetSize()) > size) {
result = data->SetSize(size);
}
}
else {
if (result == AEE_HASH_MORE_DATA) {
if (size < 0) {
return SFERR_FAILED;
}
if ((result = data->SetSize(size)) == SFERR_NO_ERROR) {
result = IHASH_GetResult(interface_cast(this), static_cast<BytePtr>(data->GetBuffer()), &size);
}
}
}
return result;
}// SFBHash::GetResult //
/*public */Void SFBHash::Update(SFXBufferPtr data)
{
if (data == null) {
return;
}
IHASH_Update(interface_cast(this), static_cast<BytePtr>(data->GetBuffer()), data->GetSize());
return;
}// SFBHash::Update //
メンバー関数のインライン展開 | |
---|---|
メンバ関数はインライン 関数で実装するのが望ましいのですが、 SophiaFramework UNIVERSE のクラスを引数に渡せるメンバ関数のうちいくつかは処理が複雑になりインライン展開できません。 そのため普通の関数として実装します。 BREW SDK で用意される型の引数を渡すメンバ関数はすべてインライン展開できますので、 インライン関数として実装します。 |
IBitmapDev インターフェースのラッパークラス SFBBitmapDev の作成方法について説明します。
IBitmapDev インターフェース | |
---|---|
IBitmapDev インターフェースは IQI_QueryInterface 関数を使用してそのインスタンスを生成するインターフェースです。 |
これらのラッパークラスでは SFBQuery クラスを継承することと、 NewInstance メンバ関数の実装において FactoryByQuery 関数を使う点が ISHELL_CreateInstance 関数でインスタンスを生成するインターフェースの場合と異なります。
IBitmapDev インターフェースのラッパークラス SFBBitmapDev を定義します。
IBitmapDev インターフェースは IQI インターフェースを継承するので、 SFBBitmapDev クラスは IQI インターフェースのラッパークラス SFBQuery クラスを継承します。
IQI インターフェースと IBase インターフェースの継承関係 | |
---|---|
IQI インターフェースは IBase インターフェースを継承するので、 IQI インターフェースのラッパークラス SFBQuery は IBase インターフェースのラッパークラス SFBBase クラスを継承します。 |
メンバ関数として SFBBitmapDev::NewInstance 関数を追加します。 この関数は スマートポインタで管理される SFBBitmapDev クラスのインスタンスを生成するための関数です。
IBitmapDev_Update / IBitmapDev_IsEnabled / IBitmapDev_NotifyEnable 関数については、 ラッパークラスのメンバ関数をインライン関数として実装します。
NotifyEnable 関数では、 SophiaFramework UNIVERSE 独自の SFXCallback クラスを引数として渡せるように定義しています。
例 21.18. SFBBitmapDev ラッパークラスの定義
// SFBBitmapDev ラッパークラスの定義 #include <SFBWrapper/SFBEnvironment.h.hpp> #include <AEEBitmap.h> #include <SFBWrapper/SFBQuery.h.hpp> // SFXCallback クラスの便利な型を自動生成するマクロ SFMTYPEDEFCLASS(SFXCallback) // SFBBitmap ラッパークラスの便利な型を自動生成するマクロ SFMTYPEDEFWRAPPER(SFBBitmap) // SFBBitmapDev ラッパークラスの便利な型を自動生成するマクロ SFMTYPEDEFWRAPPER(SFBBitmapDev) class SFBBitmapDev : public SFBQuery { // SFBBitmapDev は SFBQuery を継承する // ラッパークラスのインスタンスのコピーを禁止するマクロ SFMSEALWRAPPER(SFBBitmapDev) // ラッパークラスの継承関係を記述するマクロ SFMWRAPPERINSTANTIATETWO(SFBBitmapDev, SFBQuery, SFBBase) public: static SFBBitmapDevSmp NewInstance (SFBBitmapSmpConstRef bitmap, SFCErrorPtr exception = null); static SFBBitmapDevSmp NewInstance (SFBBitmapSmpConstRef bitmap, AEECLSID id, SFCErrorPtr exception = null); SFCError Update (Void); // this function is not supported by BREW API Reference 2.0, 2.1 Bool IsEnabled (Void); // this function is not supported by BREW API Reference 2.0, 2.1 // SophiaFramework UNIVERSE の SFXCallback クラスを引数として渡せるようにしたメンバ関数 SInt32 NotifyEnable (SFXCallbackPtr callback); // this function is not supported by BREW API Reference 2.0, 2.1 }; // BREW インターフェースとラッパークラスの型変換の関数を宣言するマクロ SFMWRAPPERINTERFACECASTDECLARE(SFBBitmapDev, IBitmapDev)
IBase インターフェースの関数 | |
---|---|
IBitmapDev_AddRef / IBitmapDev_Release 関数は IBASE_AddRef / IBASE_Release 関数を継承する関数です。 これらの関数については IBitmapDev インターフェースが継承する IBase インターフェースの ラッパークラス SFBBase 内で既に実装されているので、 SFBBitmapDev クラスで定義する必要はありません。 なお、SophiaFramework UNIVERSE ではスマートポインタを利用しているので、 インスタンスの参照カウントに関わる IBASE_AddRef / IBASE_Release 関数は private 関数として実装し、 この関数にアクセスできない設計になっています。 |
IQI インターフェースの関数 | |
---|---|
IBitmapDev_QueryInterface 関数は IQueryInterface インターフェースの IQI_QueryInterface 関数を継承する関数です。 この関数については IBitmapDev インターフェースが継承する IQI インターフェースの ラッパークラス SFBQuery 内で既に実装されているので、 SFBBitmapDev クラスで定義する必要はありません。 |
SFMTYPEDEFCLASS マクロ | |
---|---|
SFMTYPEDEFCLASS は、 引数に指定したクラスに関する便利なユーザー定義型を自動生成するマクロです。 |
SFMTYPEDEFWRAPPER マクロ | |
---|---|
SFMTYPEDEFWRAPPER は、 引数に指定したラッパークラスに関する便利なユーザー定義型を自動生成するマクロです。 SFBBitmapDevSmp 型は SFMTYPEDEFWRAPPER(SFBBitmapDev) マクロで定義されます。 |
SFMSEALWRAPPER マクロ | |
---|---|
SFMSEALWRAPPER は ラッパークラスのインスタンスのコピーを禁止するマクロです。 ラッパークラスのインスタンスはコピーしてはいけません。 |
SFMWRAPPERINSTANTIATETWO マクロ | |
---|---|
SFMWRAPPERINSTANTIATETWO はラッパークラスの継承関係を記述するマクロです。 IBase インターフェースからの継承関係をこのマクロを使用して記述します。 IBitmapDev インターフェースは IQI インターフェースを、 IQI インターフェースは IBase インターフェースをそれぞれ継承するので、 SFBBitmapDev クラスは SFBQuery クラスを、 SFBQuery クラスは SFBBase クラスを継承することになります。 そのため、SFMWRAPPERINSTANTIATETWO(SFBBitmapDev, SFBQuery, SFBBase) とマクロ宣言します。 RealView Compilation Tools for BREW 1.2 コンパイラの不具合を回避するためのマクロです。 RealView Compilation Tools for BREW 1.2 以外のコンパイラでは無視されます。 |
SFMWRAPPERINTERFACECASTDECLARE マクロ | |
---|---|
SFMWRAPPERINTERFACECASTDECLARE は BREW インターフェースとラッパークラス間の型変換を行う interface_cast 関数を宣言するためのマクロです。 SFMWRAPPERINTERFACECASTDECLARE(SFBBitmapDev, IBitmapDev) マクロにより、 SFBBitmapDev から IBitmapDev、 または IBitmapDev から SFBBitmapDev に interface_cast 演算子を使用してそれぞれ型変換できる関数が宣言されます。 |
SFBBitmapDev::NewInstance 関数 は SFBBase::FactoryByQuery 関数を使用して次のように実装します。
例 21.19. SFBBitmapDev::NewInstance 関数の実装方法
// SFBBitmapDev::NewInstance 関数の実装
#include <SFBWrapper/SFBBitmapDev.h.hpp>
#include <SFBWrapper/SFBBitmap.h.hpp>
/*public static */SFBBitmapDevSmp SFBBitmapDev::NewInstance(SFBBitmapSmpConstRef bitmap, SFCErrorPtr exception)
{
return static_pointer_cast<SFBBitmapDev>(FactoryByQuery(bitmap, AEEIID_BITMAPDEV, exception));
}// SFBBitmapDev::NewInstance //
/*public static */SFBBitmapDevSmp SFBBitmapDev::NewInstance(SFBBitmapSmpConstRef bitmap, AEECLSID id, SFCErrorPtr exception)
{
return static_pointer_cast<SFBBitmapDev>(FactoryByQuery(bitmap, id, exception));
}// SFBBitmapDev::NewInstance //
SFBBitmapDevSmp スマートポインタ | |
---|---|
SFBBitmapDevSmp は SFBBitmapDev のインスタンスを管理するスマートポインタの型です。 この型は SFMTYPEDEFWRAPPER(SFBBitmapDev) マクロで定義されています。 |
SFBBitmapDev クラスのメンバ関数をインライン関数を使用して実装します。
その他のメンバ関数の実装は ISHELL_CreateInstance 関数でインスタンスを生成するインターフェースの場合と同じです。
例 21.20. SFBBitmapDev クラスのメンバ関数の実装
#include <SFBWrapper/SFBEnvironment.h.hpp> #include <SFXGeneral/SFXCallback/SFXCallback.h.hpp> /*public */inline SFCError SFBBitmapDev::Update(Void) { return IBITMAPDEV_Update(interface_cast(this)); }// SFBBitmapDev::Update // /*public */inline Bool SFBBitmapDev::IsEnabled(Void) { return IBITMAPDEV_IsEnabled(interface_cast(this)); }// SFBBitmapDev::IsEnabled // /*public */inline SInt32 SFBBitmapDev::NotifyEnable(SFXCallbackPtr callback) { return IBITMAPDEV_NotifyEnable(interface_cast(this), interface_cast(callback)); }// SFBBitmapDev::NotifyEnable // SFMWRAPPERINTERFACECASTIMPLEMENT(SFBBitmapDev, IBitmapDev)
SFMWRAPPERINTERFACECASTIMPLEMENT マクロ | |
---|---|
SFMWRAPPERINTERFACECASTIMPLEMENT は BREW インターフェースとラッパークラス間の型変換を行う interface_cast 関数を実装するためのマクロです。 SFMWRAPPERINTERFACECASTIMPLEMENT(SFBBitmapDev, IBitmapDev) マクロにより、 SFBBitmapDev から IBitmapDev、 または IBitmapDev から SFBBitmapDev に interface_cast 演算子を使用してそれぞれ型変換できる関数が実装されます。 |
他の BREW インターフェースでインスタンスを生成するインターフェースの C++ ラッパークラスでは、NewInstance 関数を定義、実装する必要はありません。
これ以外は、ISHELL_CreateInstance 関数でインスタンスを生成するインターフェースや IQI_QueryInterface 関数でインスタンスを生成するインターフェースと同じです。
スマートポインタを利用するラッパークラスの実装では、 BREW インターフェースのインスタンスを返す関数のラッパークラスのメンバ関数を実装するときは 参照カウントが増減しないように注意する必要があります。
たとえば、ISHELL_LoadImage 関数のラッパークラスのメンバ関数 SFBShell::LoadImage の場合、ISHELL_LoadImage 関数は IImage インターフェースのインスタンスを返します。
これを SFBImageSmp スマートポインタとして返すときに、 interface_cast 演算子を使用して IImage インターフェースから SFBImage に型変換するだけでなく、 SFBImageSmp の 2 つめの初期化パラメータに false を指定して参照カウントを増やさないようにしています。
例 21.21. SFBShell::LoadImage 関数の実装
/*public */inline SFBImageSmp SFBShell::LoadImage(ACharConstPtr file) { return SFBImageSmp(interface_cast(ISHELL_LoadImage(interface_cast(this), file)), false); }// SFBShell::LoadImage //
参照: interface_cast 演算子 | SFBShell::LoadImage | SFXBrewPointer
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |