PrevNextUpHome SophiaFramework UNIVERSE 5.3

21.2. How to Develop the C++ Wrapper Class

There are three types of BREW interface as follows:

  1. BREW interface whose instance is created by the ISHELL_CreateInstance() function
  2. BREW interface whose instance is created by the IQI_QueryInterface() function
  3. BREW interface whose instance is created by the other BREW interface.

The method to implement the C++ wrapper class for each BREW interface above differs only in how to create the instance, i.e., the NewInstance() function.

Concretely as follows:

  1. In case of the BREW interface whose instance is created by the ISHELL_CreateInstance() function, the NewInstance() function is implemented using the SFBBase::FactoryByCreate function.
  2. In case of the BREW interface whose instance is created by the IQI_QueryInterface() function, the NewInstance() function is implemented using the SFBBase::FactoryByQuery function
  3. In case of the BREW interface whose instance is created by the other BREW interface, there is no need to implement the NewInstance() function.

21.2.1. BREW Interface whose Instance is Created by the ISHELL_CreateInstance() Function

The method to implement the C++ wrapper class "SFBHash" for the IHash Interface is described here as an example.

[Tip] About the IHash interface

The IHash interface is the BREW interface whose instance is created by the ISHELL_CreateInstance() function.

The development of the C++ wrapper class consists of the definition of the C++ wrapper class and the implementation of its member functions.

21.2.1.1. Define the C++ Wrapper Class

SFBHash, C++ wrapper class for the IHash interface, is defined as below.

Since the IHash interface inherits from the IBase interface, the SFBHash class inherits from the SFBBase wrapper class for the IBase interface.

The SFBHash::NewInstance function that is not included in the IHash interface is added. This function creates the instance of the SFBHash class managed by smart pointer.

Next, SFBHash::GetResult, SFBHash::Restart, SFBHash::SetKey, and SFBHash::Update are defined as member functions of the C++ wrapper class for IHASH_GetResult(), IHASH_Restart(), IHASH_SetKey(), and IHASH_Update() respectively.

As the sample code below, some member function may have an argument for passing the SophiaFramework UNIVERSE class such as SFXBuffer.

Example 21.8. Define the SFBHash wrapper class

// define SFBHash wrapper class
#include <SFBWrapper/SFBEnvironment.h.hpp>
#include <AEESecurity.h>
#include <SFBWrapper/SFBBase.h.hpp>
// this macro generates useful types for SFXBuffer
SFMTYPEDEFCLASS(SFXBuffer) 
// this macro generates useful types for SFBHash
SFMTYPEDEFWRAPPER(SFBHash) 
class SFBHash : public SFBBase { // SFBHash inherits from SFBBase
    // this macro prohibits copying instance of wrapper class 
    SFMSEALWRAPPER(SFBHash) 
    // this macro describes the inheritance relation among wrapper classes
    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);
                // member function that can pass SFXBuffer class of SophiaFramework UNIVERSE as an argument    
                SFCError    GetResult    (SFXBufferPtr data);
                SFCError    SetKey       (SFXBufferConstRef key);
                Void        Update       (SFXBufferPtr data);
};
// this macro declares type conversion function between BREW interface and wrapper class
SFMWRAPPERINTERFACECASTDECLARE(SFBHash, IHash)
[Note] Functions of the IBase interface

IHASH_AddRef() and IHASH_Release() are the functions that inherit from IBASE_AddRef() and IBASE_Release() respectively.

There is no need to define these functions in the SFBHash class since they have already been implemented in the SFBBase wrapper class for the IBase interface.

In addition, these wrapper functions for IBASE_AddRef() and IBASE_Release() that have something to do with reference count are implemented as private function and cannot be accessed since SophiaFramework UNIVERSE utilizes the smart pointer function.

[Tip] SFMTYPEDEFCLASS macro

SFMTYPEDEFCLASS is a macro that generates useful user-defined types for the specified class as an argument.

Reference: SFMTYPEDEFCLASS macro

[Tip] SFMTYPEDEFWRAPPER macro

SFMTYPEDEFWRAPPER is a macro that generates useful user-defined types for the wrapper class specified as an argument. For instance, the SFBHashSmp type is defined by the SFMTYPEDEFWRAPPER(SFBHash) macro.

Reference: SFMTYPEDEFWRAPPER macro

[Tip] SFMSEALWRAPPER macro

SFMSEALWRAPPER is a macro that prohibits copying a wrapper class instance. Copying an instance of wrapper class is not allowed.

Reference: SFMSEALWRAPPER macro

[Tip] SFMWRAPPERINSTANTIATEONE macro

SFMWRAPPERINSTANTIATEONE is a macro that describes the inherihance relation on wrapper classes. The inherihance relation starting at the IBase interface must be specified using this macro.

Since the IHash interface inherits from the IBase interface, when the wrapper class for the IBase interface is the SFBBase class and the wrapper class for the IHash interface is the SFBHash class, declare the SFMWRAPPERINSTANTIATEONE(SFBHash, SFBBase) macro.

In the SFBBase class, since this class is the highest in the inheritance relation, declare SFMWRAPPERINSTANTIATEZERO(SFBBase) using the SFMWRAPPERINSTANTIATEZERO macro.

There are three warpper classes called A, B, and C. B inherits from A and C inherits from B respectively. Then declare SFMWRAPPERINSTANTIATETWO(C, B, A) using the SFMWRAPPERINSTANTIATETWO macro.

In case of four wrapper classes of A, B, C, amd D, declare the SFMWRAPPERINSTANTIATETHREE(D, C, B, A) macro.

This macro is necessary for avoiding a bug of RealView Compilation Tools for BREW 1.2 compiler. This macro is ignored with compilers other than RealView Compilation Tools for BREW 1.2.

Reference: SFMWRAPPERINSTANTIATE macro

[Tip] SFMWRAPPERINTERFACECASTDECLARE macro

SFMWRAPPERINTERFACECASTDECLARE is a macro that declares the interface_cast function to convert type between BREW interface and its wrapper class.

With the SFMWRAPPERINTERFACECASTDECLARE(SFBHash, IHash) macro, type conversion functions from SFBHash to IHash or vice-versa are declared using the interface_cast operator.

Reference: interface_cast operator

21.2.1.2. Implement the NewInstance Member Function

Implement the SFBHash::NewInstance function using the SFBBase::FactoryByCreate function as follows:

Example 21.9. Implement the SFBHash::NewInstance function

// Implement the SFBHash::NewInstance function
#include <SFBWrapper/SFBHash.h.hpp>
/*public static */SFBHashSmp SFBHash::NewInstance(AEECLSID id, SFCErrorPtr exception)
{
    // implement NewInstance() using FactoryByCreate()
    // downcast with static_pointer_cast macro
    return static_pointer_cast<SFBHash>(FactoryByCreate(id, exception));
}// SFBHash::NewInstance //
[Tip] About the SFBHashSmp smart pointer

SFBHashSmp is the type of smart pointer that manages the SFBHash instance. This type is defined by the SFMTYPEDEFWRAPPER(SFBHash) macro.

Reference: SFMTYPEDEFWRAPPER macro

21.2.1.3. Implement other Member Functions

Implement the member functions of SFBHash class.

As for the SFBHash::SetKey function, implementation of standard BREW member function and extended member function with an argument of SophiaFramework UNIVERSE class is described as below.

Example 21.10. Implement SFBHash::SetKey function that wraps IHASH_SetKey() [1]

// define SFBHash::SetKey() [1]
#include <SFBWrapper/SFBEnvironment.h.hpp>
// avoid performance deterioration by wrapping with inline function
/*public */inline SFCError SFBHash::SetKey(VoidConstPtr key, SInt32 keySize)
{
    // call IHASH_SetKey() of BREW interface
    return IHASH_SetKey(interface_cast(this), static_cast<ByteConstPtr>(key), keySize);
}// SFBHash::SetKey //

Example 21.11. Implement SFBHash::SetKey function that wraps IHASH_SetKey() [2] (SophiaFramework UNIVERSE extended member function)

// define SFBHash::SetKey() [2]
#include <SFBWrapper/SFBEnvironment.h.hpp>
#include <SFXBuffer/SFXBuffer.h.hpp>
// avoid performance deterioration by wrapping with inline function
/*public */inline SFCError SFBHash::SetKey(SFXBufferConstRef key)
{
    // call IHASH_SetKey() of BREW interface 
    // extend to pass SFXBuffer class of SophiaFramework UNIVERSE via an argument
    return IHASH_SetKey(interface_cast(this), static_cast<ByteConstPtr>(key.GetBuffer()), key.GetSize());
}}// SFBHash::SetKey //

Example 21.12. Implement SFBHash::GetResult() for wrapping IHASH_GetResult() of IHash interface (SophiaFramework UNIVERSE extended member function)

// implement SFBHash::GetResult() (cannot implement as an inline function)
#include <SFBWrapper/SFBHash.h.hpp>
// extend to pass SFXBuffer class of SophiaFramework UNIVERSE via an argument
/*public */SFCError SFBHash::GetResult(SFXBufferPtr data)
{
    if (data == null) {
        return SFERR_INVALID_PARAM;
    }

    SIntN size(data->GetSize());
    // call IHASH_GetResult() of BREW interface
    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) {
               // call IHASH_GetResult() of BREW interface
               result = IHASH_GetResult(interface_cast(this), static_cast<BytePtr>(data->GetBuffer()), &size);
            }
        }
    }

    return result;
}// SFBHash::GetResult //

The following is the implementation code for all the member functions of SFBHash class.

Example 21.13. Ref 1 : Implement member functions of SFBHash with infine function

// implement member functions of SFBHash with infine function
#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)
[Tip] SFMWRAPPERINTERFACECASTIMPLEMENT macro

SFMWRAPPERINTERFACECASTIMPLEMENT is a macro that implements the interface_cast function to convert type between BREW interface and its wrapper class.

With the SFMWRAPPERINTERFACECASTIMPLEMENT(SFBHash, IHash) macro, type conversion functions from SFBHash to IHash or vice-versa are implemented using the interface_cast operator.

Reference: interface_cast operator

Example 21.14. Ref 2 : Implement member functions of SFBHash without infine function

// implement member functions of SFBHash without infine function
#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 //
[Note] About inline expansion of member function

Though a member function had better be implemented as a inline function, some functions of which a SophiaFramework UNIVERSE class can be passed as an argument are complex and cannot be inline-expanded. Therefore such a function is implemented as a normal function.

Since member functions that pass a type of BREW SDK as an argument can be inline-expanded, they are implemented as inline functions.

21.2.2. BREW Interface whose Instance is Created by the IQI_QueryInterface() Function

The method to implement the C++ wrapper class "SFBBitmapDev" for the IBitmapDev Interface is explained as an example.

[Tip] About the IBitmapDev interface

The IBitmapDev interface is an interface that creates its instance using the IQI_QueryInterface() function.

Difference from the BREW interface that creates its instance using the ISHELL_CreateInstance() function is that this wrapper class inherits from the SFBQuery class and the FactoryByQuery() function is used in implementation of the NewInstance() member function.

21.2.2.1. Define a C++ Wrapper Class

Define the SFBBitmapDev wrapper class for the IBitmapDev interface.

Since the IBitmapDev interface inherits from the IQI interface, the SFBBitmapDev class inherits from the SFBQuery wrapper class for the IQI interface.

[Tip] Inheritance relation between the IQI interface and the IBase interface

Since the IQI interface inherits from the IBase interface, the SFBQuery wrapper class for the IQI interface inherits from the SFBBase wrapper class for the IBase interface.

Add the SFBBitmapDev::NewInstance function that is not included in the IBitmapDev interface. This function is for creating the instance for SFBBitmapDev class that is managed by smart pointer.

Implement wrapper classes for IBitmapDev_Update(), IBitmapDev_IsEnabled(), and IBitmapDev_NotifyEnable() as member functions of its wrapper class.

The NotifyEnable() member function is extended to pass the SFXCallback class of SophiaFramework UNIVERSE as an argument.

Example 21.15. Define the SFBBitmapDev wrapper class

// define the SFBBitmapDev wrapper class
#include <SFBWrapper/SFBEnvironment.h.hpp>
#include <AEEBitmap.h>
#include <SFBWrapper/SFBQuery.h.hpp>

// macro that generates useful types for the SFXCallback class
SFMTYPEDEFCLASS(SFXCallback)
// macro that generates useful types for the SFBBitmap wrapper class
SFMTYPEDEFWRAPPER(SFBBitmap)
// macro that generates useful types for the SFBBitmapDev wrapper class
SFMTYPEDEFWRAPPER(SFBBitmapDev)
class SFBBitmapDev : public SFBQuery { // SFBBitmapDev inherits from SFBQuery
    // macro that prohibits copying a wrapper class instance
    SFMSEALWRAPPER(SFBBitmapDev)
    // macro that describes the inheritance relation of wrapper class
    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
                // member function that can pass SFXCallback class of SophiaFramework UNIVERSE as an argument
                SInt32           NotifyEnable (SFXCallbackPtr callback); // this function is not supported by BREW API Reference 2.0, 2.1
};

// macro that declares the type conversion function between BREW interface and wrapper class
SFMWRAPPERINTERFACECASTDECLARE(SFBBitmapDev, IBitmapDev)
[Note] Functions of the IBase interface

IBitmapDev_AddRef() and IBitmapDev_Release() are inheritance functions of IBASE_AddRef() and IBASE_Release() respectively.

These functions need not to be defined in the SFBBitmapDev class since they have already been implemented in the SFBBase wrapper class for the IBase interface.

In addition, these wrapper functions for IBASE_AddRef() and IBASE_Release() that have something to do with reference count are implemented as private function and cannot be accessed since SophiaFramework UNIVERSE utilizes smart pointer fun

[Note] Functions of the IQI interface

IBitmapDev_QueryInterface() inherits from IQI_QueryInterface() of the IQueryInterface interface.

This function need not to be defined in the SFBBitmapDev class since they have already been implemented in the SFBQuery wrapper class for the IQI interface.

[Tip] SFMTYPEDEFCLASS macro

SFMTYPEDEFCLASS is a macro that generates useful user-defined types for the specified class as an argument.

Reference: SFMTYPEDEFCLASS macro

[Tip] SFMTYPEDEFWRAPPER macro

SFMTYPEDEFWRAPPER is a macro that generates useful user-defined types for the wrapper class specified as an argument. For instance, the SFBHashSmp type is defined by the SFMTYPEDEFWRAPPER(SFBHash) macro.

Reference: SFMTYPEDEFWRAPPER macro

[Tip] SFMSEALWRAPPER macro

SFMSEALWRAPPER is a macro that prohibits copying a wrapper class instance. Copying an instance of wrapper class is not allowed.

Reference: SFMSEALWRAPPER macro

[Tip] SFMWRAPPERINSTANTIATETWO macro

SFMWRAPPERINSTANTIATETWO is a macro that describes the inherihance relation on wrapper classes. The inherihance relation starting at the IBase interface must be specified using this macro.

Since the IBitmapDev interface inherits from the IQI interface and the IQI interface inherits from the IBase interface, the SFBBitmapDev class and the SFBQuery class inherit from the SFBQuery class and the SFBBase class respectively.

Therefore, declare the SFMWRAPPERINSTANTIATETWO(SFBBitmapDev, SFBQuery, SFBBase) macro.

This macro is necessary for avoiding a bug of RealView Compilation Tools for BREW 1.2 compiler. This macro is ignored with compilers other than RealView Compilation Tools for BREW 1.2.

Reference: SFMWRAPPERINSTANTIATE macro

[Tip] SFMWRAPPERINTERFACECASTDECLARE macro

SFMWRAPPERINTERFACECASTDECLARE is a macro that declares the interface_cast function to convert type between BREW interface and its wrapper class.

With the SFMWRAPPERINTERFACECASTDECLARE(SFBBitmapDev, IBitmapDev) macro, type conversion functions from SFBBitmapDev to IBitmapDev or vice-versa are declared using the interface_cast operator.

Reference: interface_cast operator

21.2.2.2. Implement the NewInstance Member Function

Implement the SFBBitmapDev::NewInstance function using the SFBBase::FactoryByQuery function as follows:

Example 21.16. Implement the SFBBitmapDev::NewInstance function

// implement the SFBBitmapDev::NewInstance function
#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 //
[Tip] About the SFBBitmapDevSmp smart pointer

SFBBitmapDevSmp is the type of smart pointer that manages the SFBBitmapDev instance. This type is defined by the SFMTYPEDEFWRAPPER(SFBBitmapDev) macro.

Reference: SFMTYPEDEFWRAPPER macro

21.2.2.3. Implement other Member Functions

Implement the member functions of SFBBitmapDev class with inline function.

The method to implement other Member Functions is same as the BREW interface that creates its instance using the ISHELL_CreateInstance() function.

Example 21.17. Implement the member functions of SFBBitmapDev class

#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)
[Tip] SFMWRAPPERINTERFACECASTIMPLEMENT macro

SFMWRAPPERINTERFACECASTIMPLEMENT is a macro that implements the interface_cast function to convert type between BREW interface and its wrapper class.

With the SFMWRAPPERINTERFACECASTIMPLEMENT(SFBBitmapDev, IBitmapDev) macro, type conversion functions from SFBBitmapDev to IBitmapDev or vice-versa are implemented using the interface_cast operator.

Reference: interface_cast operator

21.2.3. BREW Interface whose Instance is Created by the other BREW Interface

For the BREW interface which creates its instance using the other BREW interface, the NewInstance() function does not have to be defined and implemented.

Other than this are same as the BREW interface that creates its instance using the ISHELL_CreateInstance() function or the BREW interface that creates its instance using the IQI_QueryInterface() function.

21.2.4. Reference Count

Since a smart pointer is used in the implementation of a wrapper class, make sure to neither increase nor decrease the reference count when implementing a member function which returns the instance of BREW interface.

For instance, the member function SFBShell::LoadImage of wrapper class for the ISHELL_LoadImage(), ISHELL_LoadImage() returns the instance of IImage interface.

When returning this as a smart pointer, not only convert the IImage interface into the SFBImage class using interface_cast operator, but also make the reference count not increase nor decrease by specifying false as the second argument for intialization of the SFBImageSmp class.

Example 21.18. Implement SFBShell::LoadImage()

/*public */inline SFBImageSmp SFBShell::LoadImage(ACharConstPtr file)
{
    return SFBImageSmp(interface_cast(ISHELL_LoadImage(interface_cast(this), file)), false);
}// SFBShell::LoadImage //

Reference: interface_cast operator | SFBShell::LoadImage | SFXBrewPointer