ホーム > デベロッパ > SophiaFramework > BREW C++ 逆引きコード集

BREW C++ プログラミング 逆引きコード集 : トラブル

SophiaFramework を用いたBREW アプリ作成中のトラブルを対処する方法です。

独自にルート証明書を追加して https 通信を行う方法

https 通信を行うとき、サーバ証明書が使用するCA証明書が SSLROOTCERTS クラスに含まれない場合、BREW アプリ側で独自にルート証明書を追加する必要があります。

SophiaFramework UNIVERSE では、以下のようにして https 通信を行います。

  1. SFBX509Chain インスタンスを生成します。
  2. SFXFile , SFXPath , SFXBinaryStreamReader , SFXBuffer クラスを使って、DERエンコードされたCA証明書をバイナリデータとして読み込みます。
  3. SFBX509Chain::AddCert 関数を呼び出して、[1] で生成した SFBX509Chain インスタンスにWEBOPT_X509_ROOT_CERTS (ルート認証機関の証明書) として [2] で読み込んだ証明書(バイナリ形式)をセットします。
  4. SFXHTTPConnection::Open 関数を呼び出して https 通信をオープンします。
  5. SFXHTTPConnection::SetTrustMode 関数を呼び出して、認証モードを "SSL_TRUST_MODE_FAIL" に設定します。
  6. SFXHTTPConnection インスタンスが内部に保持する SFBWeb インスタンスを取得します。
  7. SFBWeb::AddOpt 関数を呼び出して、SFBWeb インスタンスにWEBOPT_DEFAULTSとして[1]で生成した SFBX509Chain インスタンスを追加します。
  8. SFXHTTPConnection::Connect 関数を呼び出して、https 接続を行い、以下 https プロトコルでデータ通信を行います。
  9. 最後に、SFXHTTPConnection::Close 関数を呼び出して https 通信をクローズします。

具体的なコードについては、下記のサンプルコードをご覧ください。

サンプルコードダウンロード( httpsapp.zip: 21.3kb )

(注)CA証明書読み込み時のバッファ(  SFXBuffer )および SFBX509Chain インスタンスを明示的に解放する場合は、SFXHTTPConnection::Close 関数呼出し後に行わなければいけません。そのため、CA証明書の読み込みおよび SFBX509Chain インスタンスの生成は、SFXHTTPConnection::Open 関数呼び出し前に行うことを推奨します。
      

BREW 3.1 端末でHTTPS 通信を高速化する方法

QUALCOMM 社の情報によりますと、 BREW3.1.2 以前の実装では、ISSL インターフェースが過剰にパケットを細分化するため HTTPS 通信のパフォーマンスが劣化するらしいです。(参照:関連情報)

この問題を解決するためには、 下記のように SFXHTTPConnection クラスを開いてから接続するまでの間に、 SFXHTTPConnection クラスが内部で保持する SFBWeb インスタンスを取得して、この問題が解決されている ISSL インターフェースのクラス ID「AEECLSID_SSL_101」を渡すようにします。

なお、関連情報には、 『本機能は利用例が少なく、十全な評価がされていないため、使用のリスクは御社でご判断下さい』とあります。

#include "AEESSL_WEBOPT_CLASSID.h"
#include "ISSL.bid"

_http.Open()

SFBWebOpts webopts = SFBWebOpts::NewInstance(&error);
WebOpt opt[2];
opt[0].nId = WEBOPT_SSL_CLASSID;
opt[0].pVal = (VoidPtr)AEECLSID_SSL_101;
opt[1].nId = WEBOPT_END;
opt[1].pVal = null;
webopts->AddOpt(opt);
SFBWebSmp web = _http.GetSFBWeb();
web->AddOpt(opt);

_http.Connect(url, XALLBACK_INTERNAL(OnConnect));

※ 接続時間が短縮されたもののフェッチに時間がかかる場合は、ストリームリーダーのバッファサイズを小さくしてみてください。たとえば、4096バイト(デフォルト)を2048バイトにすることで高速化された例があります。

      

ライセンスコードを設定したが、アプリが起動しないのですが…?

ラインセンスコードを設定してアプリを起動すると、「アプリが起動できませんでした。」というエラーメッセージが端末に表示されるのですが…?

対応策:
ライセンスコードと ClassID は一対一に対応します。設定したライセンスコードに対応する ClassID がアプリに正しく設定されているか確認してください。

      

RVCT for BREW 1.2 で、「-g-」オプションでビルドするとリンクエラーが発生するのですが・・・?

RVCT for BREW 1.2 で、「-g-」オプションでビルドすると、下記のクラスに関してリンクエラーが発生するのですが、どうすれば宜しいですか?

■対応方法:

RVCT for BREW 1.2 で「-g-」オプションでビルドする場合、最適化オプション -Ospace を -Otime に変えてみてください。


※この問題は、RVCT for BREW 1.2 に付属するリンカの特性と考えられます。

      

標準トレーサに「配信条件:なし」で配信規則が登録されている BREW 定義イベントの取得方法

標準トレーサに『配信条件 : なし[SFYTracer::STATE_NONE]』で配信規則が登録されている BREW 定義イベントは、 SFYApplication クラスがデフォルトで保持するルート( SFZRoot )を含めレスポンダには配信されません。

これは標準トレーサの規則が SFYDistributer インスタンスに登録されているからです。

このイベントを取得するには、SFYDistributer インスタンスに直接ハンドラを登録する必要があります。

具体的には以下の方法で取得します。

1. SFYApplication::GetDistributer 関数を利用して SFYDistributer クラスのインスタンスを取得します。

2. SFYDistributer::RegisterHandler 関数を利用してこのイベントのハンドラを登録します。

3. このハンドラは、どこのクラスに定義してもかまいませんが、レスポンダへの登録時とは異なり、invoker パラメーターは null として呼び出されます。 invoker パラメーターを使用するときは注意が必要です。

      

描画できない

描画できない場合は以下の項目を確認してください。

・GUI フレームワークを使用したアプリ (アプリクラスが SFYApplication を継承) の場合

1. 描画ハンドラの中で描画していますか?

2. 描画ハンドラマクロの引数の graphics を使って描画していますか?

// 描画ハンドラの定義(ウィンドウ内に描画)
XANDLER_IMPLEMENT_VOIDRENDER(MyWindow, OnRenderRequest, invoker, reason, graphics)
{
    unused(invoker);
    unused(reason);

    // 四角形を描画する
    graphics->DrawRectangle(SFXRectangle(10, 10, 25, 25));
    
    // graphics->Update(); は必要なし
}

3. コンストラクタ内で描画ハンドラを登録していますか?

// コンストラクタ
MyWindow::MyWindow(Void) : ...
{
    // ハンドラを登録する(エラー処理は省略)
   RegisterHandler(
            SFXEventRange(SFEVT_RESPONDER_RENDER, SFEVT_RESPONDER_RENDER,
                                        SFP16_RENDER_REQUEST, SFP16_RENDER_REQUEST),
            XANDLER_INTERNAL(OnRenderRequest));

    return;
}

・GUI フレームワークを使用しないアプリ (アプリクラスが SFCApplication を継承) の場合

1. グラフィックス・インターフェースを取得していますか?

SFXGraphicsPtr graphics;

// グラフィックス・インターフェースを取得する
graphics = SFXGraphics::GetInstance();

// 四角形を描画する
graphics->DrawRectangle(SFXRectangle(10, 10, 25, 25));

2. SFXGraphics::Update 関数を呼び出していますか?

graphics->Update();

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照: リファレンス 3.1. SFY アプレット | リファレンス 5.5. カスタマイズ

      

mod ファイルを作成できない

コンパイル時にエラーが発生せず、mod ファイル作成時に以下のエラーが発生する場合があります。

non-POD object cannot be passed as '...' argument

このエラーメッセージは、SFXHelper関数使用時のエラーの可能性があります。(BREW関数使用時にも同様のエラーが起きる可能性があります。)

以下にエラー出力例を記述します。

// 例 : SFXHelper::dbgprintf を使用したとき

// NGの記述例
SFXAnsiString str
SFXHelper::dbgprintf("%s", str); // C 言語の文字列に変換していないのでエラー

// OKの記述例
SFXAnsiString str
SFXHelper::dbgprintf("%s", str.GetCString()); // C 言語の文字列に変換しているのでOK
      

コンパイルできない (インクルードファイル「AEEKDDI.h」のエラー)

以下のエラーメッセージが出てコンパイルできないときは、KDDI社BREW 日本拡張パッケージの定義 TARGET_EXTENSION_KDDI を削除する必要があります。

ただし、KDDI BREW 日本拡張パッケージを使用する場合は、下記の設定が必要です。このときは、KDDI BREW 日本拡張パッケージが正しくインストールされていない可能性があります。

「fatal error C1083: include ファイルを開けません。'AEEKDDI.h'」

削除手順

Visual C++ 6.0 の場合

・メニューから [プロジェクト] -> [設定] を選択する。
・[C/C++] タブを選択する。
・[プリプロセッサの定義] の項目から [TARGET_EXTENSION_KDDI] を削除し、OKボタンを押す。

Visual Studio 2003/2005 の場合

・メニューから [プロジェクト] -> [プロパティ] を選択する。
・[C/C++] フォルダから[プリプロセッサ]を選択する。
・[プリプロセッサの定義] の項目から [TARGET_EXTENSION_KDDI] を削除し、OKボタンを押す。

      

コンパイルできない (インクルードファイルのエラー)

以下のエラーメッセージが出て、コンパイルできないときは、インクルードディレクトリの設定を確認してください。

fatal error C1083: インクルードファイルがオープンできません。'SophiaFramework.hpp'

確認手順:(BREW SDK 4.0 以外の場合は、BREW SDK のバージョンに応じたライブラリファイルのパスを設定してください)

Visual C++ 6.0 の場合

Step 1.メニューから [プロジェクト] -> [設定] を選択する。

Step 2. [インクルードファイルのパスを確認する。

1) [C/C++] タブを選択する。

2) [カテゴリ] の項目から [プリプロセッサ] を選択する。

3) [インクルードファイルのパス] の入力に

$(BREWDIR)\inc;$(SFHOME)\Include 

が無い場合、これを手動で追加する。

Step 3. ライブラリファイルのパスを確認する。

1) [リンク] タブを選択する。

2) [オブジェクト/ライブラリ モジュール] の入力に

$(SFHOME)\Library\SophiaFrameworkBrew400JpnVC60.lib 

が無い場合、これを手動で追加する。

Visual Studio .NET 2003 の場合

Step 1.メニューから [プロジェクト] -> [プロパティ] を選択する。

Step 2. [インクルードファイルのパスを確認する。

1) [構成プロパティ] -> [C/C++] -> [全般] を選択する。

2) [追加のインクルード ディレクトリ] の入力に

$(BREWDIR)\inc;$(SFHOME)\Include 

が無い場合、これを手動で追加する。

Step 3. ライブラリファイルのパスを確認する。

1) [構成プロパティ] -> [リンカ] -> [入力] を選択する。

2) [追加の依存ファイル] の入力に

$(SFHOME)\Library\SophiaFrameworkBrew400JpnVCNET2003.lib

が無い場合、これを手動で追加する。

Visual Studio 2005 の場合

Step 1.メニューから [プロジェクト] -> [プロパティ] を選択する。

Step 2. [インクルードファイルのパスを確認する。

1) [構成プロパティ] -> [C/C++] -> [全般] を選択する。

2) [追加のインクルード ディレクトリ] の入力に

$(BREWDIR)\inc;$(SFHOME)\Include 

が無い場合、これを手動で追加する。

Step 3. ライブラリファイルのパスを確認する。

1) [構成プロパティ] -> [リンカ] -> [入力] を選択する。

2) [追加の依存ファイル] の入力に

$(SFHOME)\Library\SophiaFrameworkBrew400JpnVC2005.lib

が無い場合、これを手動で追加する。

      

リファレンスに記載されていないエラー番号の内容は … ?

SophiaFramework が返すエラー ( SFCError 型 ) に関して、その番号が [ 0x0000 〜 0x3FFF ] の範囲にあるものでリファレンスに記載のないものは BREW プラットフォームが返したエラーです。

これらのエラーの詳細内容については、BREW SDK に含まれる AEEError.h というファイルをご覧になってください。

      

VC6 で ClassView にクラスリストが表示されないのですが ・・・ ?

Microsoft Visual Studio C++ 6.0 には、ClassView パーサのマクロ処理に関して不具合があります。

現時点で、ヘッダファイル内コンストラクタの static_throws マクロが原因となって Microsoft Visual Studio C++ 6.0 の ClassView にクラスリストが表示されないことが分かっています。

この場合の回避策は以下のとおりです。

回避策 1. static_throws マクロの記述を削除します。

static_throws マクロはコンパイル時に削除されますので、削除しても実行時に影響は及びません。

( 開発者に例外を搬出する可能性があることを明示しているだけなので )

回避策 2. ヘッダファイルの先頭の方で

#define static_throws

と記述します。

回避策 1. または 2. により、ClassView にクラスリストは正常に表示されるようになります。

# Microsoft Visual Studio C++ 6.0 では ClassView 関連の不具合のため、他にも正常にパースできない可能性があります。 ClassView にクラスリストを表示する必要性が高い場合は、Microsoft Visual C++ .NET2003 をご利用ください。Microsoft Visual C++ .NET2003 では正常に動作します。

      

BREW SDK 3.1.5の開発環境について

SophiaFramework は BREW SDK v3.1.5 については動作保障を行っておりません。
BREW SDK 3.1.2日本語版をご使用ください。

BREW SDK 変更手順

1:BREW SDK v3.1.5 および BREW SDK v3.1.2 Ja のアンインストールを行ってください。
[設定]-[コントロールパネル]-[プログラムの追加と削除] から BREW SDK バージョン名 を選択し削除します。
2:BREW SDK v3.1.2 Jaを再インストールしてください。

      

Microsoft Visual C++6.0 の開発環境について

Microsoft Visual C++6.0 で Service Pack 6 以前の開発環境の場合、コンパイルできない可能性があります。
Service Pack 6 を入手しコンパイラ アップデートを行ってください。

<コンパイラ アップデートの入手方法と適用方法>

Service Pack の入手方法
1:Microsoft 社Microsoft Visual Studio 製品 ダウンロード情報ページを開きます。
2:製品一覧の中の、「Visual Studio 6.0」をクリックします。
3:Visual Studio 6.0 用 Service Pack 一覧の中の、「Visual Studio 6.0 Service Pack 6」をクリックします。
4:新しく開いたページの中程にある、「Visual Studio 6.0 Service Pack 6 の入手方法」のリンクをクリックします。
5:「Web サイトからのダウンロード」の一覧の中にある、「Full 版」のリンクをクリックします。
6:「言語の変更 :」が「日本語」になっていることを確認します。もし「日本語」になっていなければ「日本語」に変更してください。
7:「ダウンロード」ボタンをクリックします。ファイルの処理方法を尋ねるダイアログが表示された場合は、ディスクに保存するようにして、保存先に適当な場所を選択してください。

Service Pack のインストール
1:ダウンロードした Vs6sp6.exe を実行します。
2:ファイルの展開先フォルダを尋ねるダイアログが表示されるので、展開先を指定して、「OK」ボタンをクリックします。
3:上で展開先に指定したフォルダを開き、その中にある setupsp6.exe を実行します。
4:インストーラの指示に従って、Service Pack のインストールを完了します。

      

ARM のリンケージでエラーが発生する

ARM のリンケージでエラーが発生する場合は、以下の項目をご確認ください。

1. RVCTB のビルドバージョン (コマンドラインで armcpp と入力する)

SophiaFramework では、RealView Compilation Tools for BREW 1.2 の Build 848 が必要です。

2. ARM 用のメイクファイルのコンパイラオプション

OPT = -Ospace -O2 --no_inlinemax

になっている場合、-Ospace を -Otime に変えてみる。

      

キーを押してもキーハンドラが起動しない

キーハンドラを起動させるには、キーハンドラの定義の他に、登録が必要です。

キーハンドラはコンストラクタなどで登録します。

// コンストラクタ
MyWindow::MyWindow(Void)
{
    // OnKey ハンドラをすべてのキーイベントに反応するように登録する
    // (エラー処理は省略)
    RegisterHandler(SFEVT_KEY, HANDLER_AFTER, HANDLER_FUNCTION(OnKey));
}

クリアーキーだけに反応させる場合

RegisterHandler(SFEVT_KEY, AVK_CLR, HANDLER_AFTER,
    HANDLER_FUNCTION(OnClear));

矢印キーだけに反応させる場合

// キーコードの範囲を指定して登録する (AVK_UP から AVK_RIGHT まで)
RegisterHandler(SFEVT_KEY, AVK_UP, AVK_RIGHT, HANDLER_AFTER,
    HANDLER_FUNCTION(OnKey));