2006年02月03日

Symbian OS/C++プログラマのためのNokia Series 60アプリケーション開発ガイド

第1章 手始めに
Series 60 C++ SDK(Software Development Kits)
開発プロセスの概要
Series 60エミュレータ
エミュレータ用にビルドする
Microsoft Visual C++ IDEを使ってビルドする方法
Borland C++IDE Builder 6を使ってビルドする方法
Borland C++BuilderXを使ってビルドする方法
CodeWarrior IDEを使ってビルドする方法
エミュレータの実行
Series 60プラットフォームの実機用にビルドする
実機上に配置する
まとめ

第2章 開発リファレンス
SDKのバージョンと、その選択
Series 60 Version 1.xのSDK
Series 60 Version 2.xのSDK
HelloWorld GUIアプリケーション
HelloWorldのbid.inf
HelloWorld.mmp
ビルドと実行
HelloWorld GUIの実行部とランタイムファイル
HelloWorldのプロジェクトファイルとフォルダ
HelloWorld GUIのソースファイル
リソースコンパイラ
アプリケーションとリソースのローカライズ
AIFファイル
コンソールアプリケーション
Hello Worldコンソールアプリケーション
コンソールアプリケーションのビルドと実行
HelloWorldCon.mmp
HelloWorldConのエミュレータ実行ファイル
HelloWorldConのターゲット実行ファイル
Symbianインストレーションシステム
SISファイル用ビルドツール
.pkgファイルのフォーマット
SISファイルをビルドする
その他の開発ツール
マルチビッドマップとBmconv(ビットマップコンバータ)
Series 60用アプリケーションウィザード
その他のSDKツール
さらに、その他のツールとユーティリティ
Series 60のSDKとIDEをインストールする際のヒント
Microsoft Visual Studio .NET
エミュレータの設定
エミュレータにおけるアプリケーションのパニック
アプリケーションの配置とビルドに関する上級ガイドライン
プラットフォームUID
デバイス識別UID
リソースファイルのバージョンと圧縮方法
ARMターゲットのためののビルド
まとめ

第3章 Symbian OSの基礎
命名規約
Tクラス
Sクラス
Cクラス
Rクラス
Mクラス
名前空間
基本型
例外処理とリソース管理
例外、リーブ、パニック、トラップ
リーブの作法とクリーンアップスタック
2フェーズコンストラクション
Symbian OSにおけるコンストラクションの方法
クリーンアップスタックの応用
ディスクリプタ
階層構造
書き換え不可能API(Nonmodifiable API)
書き換え可能API(Modifiable API)
リテラル
ディスクリプタを使う
引数や戻り値の型としてのディスクリプタ
パッケージディスクリプタ
コレクションクラス
RArray型とRPointerArray型
CArray型
アクティブオブジェクトで非同期サービスを使う
アクティブスケジューラ
アクティブオブジェクト
アクティブオブジェクトを実装する
実装例
アクティブオブジェクトの落とし穴
ファイル、ストリーム、ストア
ファイル
RFs API
RFile API
ストリーム
ストア
クライアント/サーバアーキテクチャ
サーバセッション
サーバセッションとプロセス間通信
サーバ概説
サブセッション
まとめ

第4章 アプリケーション設計
アプリケーションフレームワーク
アプリケーションアーキテクチャ
中心的なアプリケーションクラス
アプリケーションの初期化
重要なAppUiメソッド
アプリケーションUIを設計する
コントロールを主体とするSymbian OSの伝統的なアーキテクチャ
ダイアログを主体とするアーキテクチャ
Avkonのビュー切替アーキテクチャ
適切なアプリケーションアーキテクチャを選ぶ
ファイル処理
UIとエンジンを分離する
ECom
EComの概要
EComインターフェース
ECom DDL
国際化
開発者のための一般的なガイドライン
OSによるローカライズのサポート
正しいアプリケーションのふるまい
疑い深く批判的なアプローチを開発に採用すること
Windowsサーバが生成するイベントを処理すること
いつでも優雅に終了すること
データを保存する前にディスク空間をチェックすること
その他のヒントとチップ
まとめ

第5章 アプリケーションUIコンポネント
コントロール
コントロールとウィンドウ
単純コントロールと複合コントロール
ウィンドウ所有権
単純コントロールの作成
複合コントロールの作成
コントロール間の関係を確立する
スキン
必ずスキンを提供するコントロール
オプションでスキンを提供するコントロール
スキンに注目するコントロール
スキンを意識しないコントロール
スキンを意識するコントロールを定義する
イベント処理
キーイベント
再描画イベント
オブザーバ
リソースファイル
リソースファイルの構文
リソースファイルの構造
メニュー
サブメニュー
メニューの基本
動的メニュー
コンテクストメニュー
ペイン
ステータスペイン
タイトルペイン
コンテクストペイン
ナビゲーションペイン
メインペイン
ソフトキーペイン
まとめ

第6章 ダイアログ
ダイアログの一般的な特徴
標準ダイアログ
単純なダイアログの作成
マルチページダイアログ
ダイアログのためのメニューを定義する
ダイアログ内のカスタムコントロール
フォーム
フォームの行
フォームのソフトキー
アプリケーションの中でフォームを作成する
ノート
ラップノート
カスタムノート
ウェイトノート
プログレスノート
グローバルノート
クエリー
データクエリー
リストクエリー
グローバルクエリーを使う
リストダイアログ
マーク付け可能リストダイアログ
まとめ

第7章 リスト
リストの基本
垂直リスト
選択リスト
メニューリスト
マーク付け可能リスト
複数選択リスト
リストのアイテムとフィールド
リストからアイテムを探す
垂直リストを使う
基本的なリスト
動的リスト
マーク付け可能リスト
ポップアップメニューリスト
グリッド
月別カレンダーグリッド
ピンボードグリッド
GMSグリッド
グリッドを使う
グリッドの基本
マーク付け可能グリッド
設定リスト
設定リストを使う
設定リストの基本
まとめ

第8章 エディタ
テキストエディタ
寸法と入力容量
キーパッド入力のフィルタリング
追加文字へのマップを提供する
プロパティ
プレインテキストエディタの構成
リッチテキストエディタの構成
スタイルを使う
数値エディタ
数値エディタの構成
シークレットエディタ
シークレットエディタを使う
マルチフィールド数値エディタ(MFNE)
IPアドレスエディタ
番号エディタ
範囲エディタ
時刻エディタ
日付エディタ
日付時刻エディタ
時間エディタ
時差エディタ
MFNEを使う
まとめ

第9章 通信の基礎
シリアル通信
シリアル通信を使う
ソケット
Series 60のソケット
クライアントとサーバ
コネクションレスソケットとコネクティッドソケット
コネクティッドソケット
セキュアソケット
TCP/IP
IPv6
Series 60のためのTCP/IPプログラミング
CommDB
マルチホーミング
赤外線通信
IrDAスタック
Series 60機器上での赤外線通信プログラミング
Bluetooth
Bluetoothの概略
サンプルBluetoothアプリケーション
サービスの宣伝
Bluetoothのセキュリティ
デバイスとサービスの発見
Bluetoothソケット通信
まとめ

第10章 より高度な通信技術
HTTP
サンプルアプリケーション
WAP
WAPアーキテクチャ
Series 60における実装
メッセージング
メッセージングの主要概念
主なメッセージングクラスとデータ型
メッセージングAPI
クライアントMTM APIを使う
Send-As APIを使う
CSendAppUiクラスを使う
着信メッセージの監視
テレフォニー
Etel APIを使う
前処理
発呼
着呼
リダイアル処理
まとめ

第11章 マルチメディア:グラフィックスとオーディオ
Series 60クラシックスアーキテクチャの概要
ウィンドウサーバ
フォントとビットマップのサーバ(FBS)
ウィンドウサーバとFBS
マルチメディアサーバ
基本描画
スクリーンの座標と幾何
グラフィックスデバイスとグラフィックスコンテクト
色と表示モード
ペンとブラシ
ウィンドウとCCoeControlの関係
フォントとテキスト
テキストとフォントの寸法
フォントの主なクラスと関数
主なフォントクラスを使い、利用可能なフォントをすべて列挙する
テキストの効果
図形
矩形
楕円形
円弧と扇型
多角形
ビットマップ
アプリケーションで使うためにビットマップを生成する
ビットマップをロードして描画する
ビットマップのマスク
ビットマップ関数
アニメーション
アニメーションアーキテクチャ
オフスクリーンビットマップとダブルバッファリング
「クライアント側」アプローチによるアニメーション
ダイレクトスクリーンアクセス(DSA)
アーキテクチャの概要
ダイレクトスクリーンアクセスのための主要なクラス
実装時に考慮すべきこと
画像の操作
画像の変換
画像の回転
画像のスケーリング
オーディオ
録音
トーン
オーディオデータ
ストリーミング
まとめ

第12章 アプリケーションのビューとエンジンや主なシステムのAPIの使い方
標準アプリケーションビューを使う
電話帳ビューの切替
カレンダービューの切替
カメラビューの切替
フォトアルバムビューの切替
プロファイルビューの切替
メッセージングビューの切替
切替できないアプリケーション
アプリケーションエンジン
ログエンジン
カメラAPI
電話帳エンジン
コンパクトビジネスカードとvCard
カレンダーエンジンのアクセス
フォトアルバムエンジン
システム機能をアクセスする
ハードウェア抽象レイヤ
システムエージェント
バイブレーションAPIのサポート
まとめ

第13章 テストとデバッグ
品質保証
コーディング規格
防衛的プログラミング
テスト
テストの戦略
テストのためのツールとテクニック
実機上とエミュレータ上のテストの違い
テストハーネス
デバッグ
エミュレータでアプリケーションをデバッグする
実機でアプリケーションをデバッグする
まとめ

付録 エミュレータのショートカット

用語集
リファレンス

Symbian OS/C++プログラマのためのNokia Series 60アプリケーション開発ガイド

Symbian OSは、音声通話以外にさまざまなデータ処理機能を持つハイエンド携帯電話(=スマートフォン)用の標準OSとして幅広く採用されていますが、そこで使用されるアプリケーションは、一般のPCソフトのようにインストールして利用できるOS固有のアプリケーション(ネイティブアプリケーション)の時代を迎えて、大きく変化しようとしています。
本書のテーマであるSymbian OS+ミドルウェア「Nokia Series 60」の環境は、その代表的な開発プラットフォームです。ヨーロッパをはじめとして海外ではすでにこの環境を実装したスマートフォンが市場を牽引していますが、日本でもノキア・ジャパンより端末の発売が発表されるなど、業界や開発者の注目を集めています。
基礎から設計、各種APIの活用、マルチメディアデータ処理、テスト・デバッグまでSymbian OS + Nokia Series 60環境での開発ノウハウのすべてを網羅した本書は、携帯電話用アプリ開発に関わるすべてのエンジニア必読の1冊です。

Symbian OS

Symbian OSではフレームワークと呼ばれるソフトウェアが走っていて、我々が作るアプリケーションはこのフレームワークにDLLとしてロードされます。つまり、アプリケーション開発ではそのDLLを開発していくことになります。

アプリケーションDLLではNewApplication()とE32Dll()がEXPORT_Cされている必要があります。E32DllはKErrNoneをリターンするだけのようです。NewApplication()ではCApaApplicationクラスのインスタンスを生成して返します。それがアプリケーションの実体です。
posted by シンビアン at 16:47| Comment(0) | TrackBack(0) | NOKIA SMARTPHONE HACKS | このブログの読者になる | 更新情報をチェックする

4種類の新しいキャスト

キャストは使わずに済ませられるならそれに越したとはないのですが、どうしても使わざるを得ないシチュエーションは少なからず存在します。

ならばせめて少しでも安全にキャストするために新たに定められたキャスト構文が、以下に挙げる static_cast / reinterpret_cast / const_cast / dynamic_cast です。

* static_cast

static_cast(expr)

static_castはexprの型からtypeへの暗黙の型変換、あるいはtypeからexprへの暗黙の型変換が存在する場合にだけキャストします。キャスト不可能であればコンパイルエラーとなります。

// int から long へ
int ival;
long lval = static_cast(ival);

reinterpret_cast

reinterpret_cast(expr)

reinterpret_castはtype(expr)が許されるなら、exprをtypeに単にキャストします。

// long から int* へ
long lval;
int* iptr = reinterpret_cast(lval);

reinterpret_castは単なる型変更であり、たとえ派生関係があったとしてもポインタのアドレス自体はキャスト前と変わりません。
その意味でreinterpret_castは非常に危険なキャストといえるでしょう。

const_cast

const_cast(expr)

const_castはconstおよびvolatile修飾子を無効にするだけのキャストを行ないます。そのほかのときはコンパイルエラーとします。

// const int* から int* へ
const int* ciptr;
int* iptr = const_cast(ciptr);

dynamic_cast

dynamic_cast(expr)

dynamic_castは基底クラスへのポインタ(or 参照)から派生クラスへのポインタ(or 参照)への型保証キャストを行ないます。
上記3種のキャストはコンパイル時にキャストしますが、dynamic_castは実行時に型の検査が行なわれ、変換不可能であれば0を返します。



class Base { ... };
class Derived : public Base { ... };

Base base;
Derived derived;

Derived* pd1 = dynamic_cast(&base); // 失敗 pd1 == 0
Derived* pd2 = dynamic_cast(&derived);


参照のキャストに失敗すると、std::bad_cast例外がthrowされます。

try {
Derived& rd1 = dynamic_cast(base);
} catch ( const std::bad_cast& e ) {
std::cout << e.what() << std::endl;
};

dynamic_castにより、従来のキャストでは不可能であった クロス・キャスト、そして抽象基底クラスからのダウン・キャストが可能になりました。

*
o クロス・キャスト

/*
* Shape と Drawable は派生関係にない
*/
class Shape {
...
};

class Drawable {
public:
virtual void draw() =0;
};

/*
* Circle は Drawable にキャスト可能
*/
class Circle : public Shape, public Drawable {
public:
virtual void draw();
};

Shape* shape = new Circle;
/* 従来のキャスト (Drawable*)shape では、
* 場合によっては暴走する */
Drawable* drawable = dynamic_cast(shape);
if ( drawable )
drawable->draw();


o 抽象基底クラスからのダウン・キャスト

class Machine {
...
};

class TV : virtual public Machine {
public:
void tune(int channel);
};

class VTR : virtual public Machine {
public:
void record();
};

class TeleVideo : public TV, public VTR {
...
};

Machine* machine = new TeleVideo;
/* 従来のキャスト (TeleVideo*)machine はコンパイルエラー */
TeleVideo* televideo = dynamic_cast(machine);
if ( televideo ) {
televideo->tune(8);
televideo->record();
}



※注意
dynamic_castが適用できるのはポリモルフィック・クラス、 すなわち少なくとも一つのメンバ関数が仮想関数でなくてはなりません。

struct non_polymorpic { ... }; // 仮想関数が存在しない
struct something : non_polumorphic { ... };
non_polymorphic* p;
something* q = dynamic_cast(p); // error!

新しいキャストは従来のキャストよりはるかに安全です。

また、grepなどで"_cast"をキーにすればキャストした個所を簡単に検索できるという副次的な効果もあります。
posted by シンビアン at 16:44| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

従来のキャストの問題点

異なる型への変換において、C/C++ではキャストが用いられます。

// intからlongへのキャスト
int ival;
int lval = (long)ival;

ご存知のとおり、キャストは非常に危険です。 本来ならば型の不一致によるコンパイルエラーをねじ伏せるのですから。

キャストの使われ方(意味)は、大きく3種(型変換/型変更/const外し)に分類されます。

1. 型変換

// int から double へ
int ival;
double dval = (double)ival;

2. 型変更

// long から int* へ
long lval;
int* iptr = (int*)lval;

3. const外し

// const int* から int* へ
const int* ciptr;
int* iptr = (int*)ciptr;

上記のどの目的でキャストしても、構文としてはどれも同じ

(型)式

です。つまりコードからは"何が目的でキャストしたのかはっきりしない"のですね。
posted by シンビアン at 16:38| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

2006年02月01日

Symbian OS C++ 実践開発技法

第1章 Symbian OSにおけるクラス名の規約

1.1 基本型
1.2 Tクラス
1.3 Cクラス
1.4 Rクラス
1.5 Mクラス
1.6 静的クラス
1.7 ご注意ください
1.8 まとめ

第2章 リーブ:Symbian OSの例外

2.1 リーブする関数
2.2 new(ELeave)を使うヒープ割り当て
2.3 コンストラクタとデストラクタ
2.4 リーブする関数の扱い方
2.5 TRAPとTRAPDを使ってリーブをトラップする
2.6 LeaveScan
2.7 まとめ

第3章 クリーンアップスタック

3.1 クリーンアップスタックを使う
3.2 クリーンアップスタックの仕組み
3.3 非CBaseクラスでクリーンアップスタックを使う
3.4 カスタマイズしたクリーンアップのためにTCleanupItemを使う
3.5 可搬性
3.6 キャストの使用に関する注意事項
3.7 まとめ

第4章 2フェーズコンストラクション

4.1 まとめ

第5章 ディスクリプタ:Symbian OSの文字列

5.1 書き換え不可能なディスクリプタ
5.2 書き換え可能なディスクリプタ
5.3 ポインタディスクリプタ
5.4 スタック上のバッファディスクリプタ
5.5 ヒープ上のバッファディスクリプタ
5.6 リテラルディスクリプタ
5.7 まとめ

第6章 ディスクリプタの正しい使い方

6.1 パラメータや戻り値の型としてのディスクリプタ
6.2 ディスクリプタの共通メソッド
6.3 ヒープディスクリプタHBufCの使い方
6.4 ディスクリプタの外部化と内部化
6.5 TFileNameの使いすぎ
6.6 ディスクリプタの操作に便利なクラス
6.7 まとめ

第7章 動的な配列をバッファ

7.1 CArrayXクラス
7.2 RArrayとRPointerArray
7.3 CArrayXではなくRArrayを使う理由
7.4 動的ディスクリプタ配列
7.5 固定長配列
7.6 動的バッファ
7.7 まとめ

第8章 アクティブオブジェクトによるイベント駆動のマルチタスク

8.1 マルチタスクの基礎
8.2 イベント駆動のマルチタスク
8.3 アクティブオブジェクトの扱い方
8.4 サンプルコード
8.5 アクティブスケジューラを持たないスレッド
8.6 アプリケーションコードとアクティブオブジェクト
8.7 まとめ

第9章 アクティブオブジェクトの実際

9.1 アクティブオブジェクトの基本
9.2 アクティブオブジェクトの役割分担
9.3 非同期サービスプロバイダの役割分担
9.4 アクティブスケジューラの役割分担
9.5 アクティブスケジューラの起動
9.6 アクティブスケジューラのネスト
9.7 アクティブスケジューラの拡張
9.8 キャンセル
9.9 要求の完了
9.10 ステートマシン
9.11 長期タスク
9.12 CIdleクラス
9.13 CPeriodicクラス
9.14 よくある間違い
9.15 まとめ

第10章 Symbian OSのスレッドとプロセス

10.1 RThreadクラス
10.2 スレッドの優先順位
10.3 実行中のスレッドを停止させる
10.4 スレッド間のデータ転送
10.5 例外処理
10.6 プロセス
10.7 まとめ

第11章 クライアント/サーバフレームワークの理論

11.1 なぜクライアント/サーバーフレームワークを持たせるのか?
11.2 クライアントとサーバは、どのように連携するのか?
11.3 クライアントとサーバは、どのように通信するのか?
11.4 クライアント/サーバフレームワークで使われるクラスは?
11.5 同期要求と非同期要求の違いは?
11.6 サーバに起動方法は?
11.7 1つのクライアントは何個の接続を持てるのか?
11.8 クライアントが接続を断つとどうなるのか?
11.9 クライアントが死ぬとどうなるのか?
11.10 サーバが死ぬとどうなるのか?
11.11 クライアント/サーバ通信はスレッドをどう使うか?
11.12 サーバがわにアクティブオブジェクトがある意味は?
11.13 ローカル(同一プロセス)サーバの利点は?
11.14 クライアント/サーバ通信のオーバーヘッドには何があるのか?
11.15 クライアントがサーバに出せる未解決要求は何個までか?
11.16 サーバ機能は拡張できるのか?
11.17 サンプルコード
11.18 まとめ

第12章 クライアント/サーバフレームワークの実践

12.1 クライアント/サーバの要求コード
12.2 クライアントのボイラープレートコード
12.3 サーバを起動し、クライアントからそれに接続する
12.4 サーバのスタートアップコード
12.5 サーバクラス
12.6 サーバのシャットダウン
12.7 サーバをアクセスする
12.8 まとめ

第13章 各種バイナリファイル

13.1 Symbian OSのEXE
13.2 Symbian OSのDLL
13.3 書き換え可能な静的データ
13.4 TLS(スレッドローカル記憶域)
13.5 DLLローダ
13.6 UID
13.7 targettype指定子
13.8 まとめ

第14章 ECOM

14.1 ECOMアーキテクチャ
14.2 ECOMインターフェイスの特徴
14.3 ファクトリメソッド
14.4 ECOMインターフェイスを実装する
14.5 リソースファイル
14.6 クライアントコードのサンプル
14.7 まとめ

第15章 パニック

15.1 「ジャストインタイム」デバッグ
15.2 正しいパニックの形式
15.3 Symbian OSにおけるパニックの分類
15.4 別スレッドにパニックを発生させる
15.5 フォールトとリーブとパニック
15.6 まとめ

第16章 アサートを使ってバグを検出する

16.1 __ASSERT_DEBUG
16.2 __ASSERT_ALWAYS
16.3 まとめ

第17章 デバッグマクロとテストクラス

17.1 ヒープチェック用マクロ
17.2 オブジェクト不変マクロ
17.3 RTestを使ったコンソールテスト
17.4 まとめ

第18章 互換性

18.1 前方互換性と後方互換性
18.2 ソース互換性
18.3 バイナリ互換性
18.4 互換性を守る方法
18.5 バイナリ互換性を守りながら何を変更できるのか?
18.6 最良の策は、将来の変更に備えること
18.7 互換性とSymbian OSのクラス型
18.8 まとめ

第19章 薄いテンプレート

19.1 まとめ

第20章 包括的で分かりやすいAPIを公開しよう

20.1 クラスのレイアウト
20.2 IMPORT_CとEXPORT_C
20.3 パラメータと戻り値
20.4 メンバデータと「関数による抽象化」
20.5 クラス名、メソッド名、パラメータ名の選択
20.6 コンパイラが生成する関数
20.7 まとめ

第21章 正しいコーディングスタイル

21.1 プログラムコードのサイズを削減する
21.2 ヒープメモリを注意して使う
21.3 スタックメモリを注意して使う
21.4 コードの効率を最大化するために共通部分式を削除する
21.5 最適化は最後の手段
21.6 まとめ

付録

コードチェックリスト
クラスの宣言
ヘッダファイル
コメント
コンストラクタ
デストラクタ
割り当てと削除
クリーンアップスタックとリーブ安全性
ループとプログラムのフロー制御
プログラムのロジック
ディスクリプタ
コンテナ

用語集

参考文献とオンラインリソース
Symbian OSに関する書籍
C++に関する書籍
インターネット上のSymbian OSリソース
posted by シンビアン at 21:55| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

Symbian Os Explained : Effective C++ Programming for Smartphones

# Mobile communication systems
# Computer programs
# Operating systems (Computers)
# C++ (Computer program language

Textual Format :Computer Applications
Academic Level :Extracurricular

Baker&Taylor

Table of Contents

Foreword xi
About This Book xiii
Who Is It For? xiv
How to Use This Book xiv
Notation and Code Conventions Used in This Book xv
Introduction to Symbian OS xvii
Author Biography xxi
Author's Acknowledgments xxiii
Symbian Press Acknowledgments xxv
Class Name Conventions on Symbian OS 1 (12)
Fundamental Types 1 (2)
T Classes 3 (1)
C Classes 4 (2)
R Classes 6 (1)
M Classes 7 (4)
Static Classes 11 (1)
Buyer Beware 11 (1)
Summary 12 (1)
Leaves: Symbian OS Exceptions 13 (16)
Leaving Functions 13 (3)
Heap Allocation Using new (ELeave) 16 (1)
Constructors and Destructors 17 (1)
Working with Leaving Functions 18 (2)
Trapping a Leave Using Trap and Trapd 20 (6)
LeaveScan 26 (1)
Summary 27 (2)
The Cleanup Stack 29 (20)
Using the Cleanup Stack 31 (4)
How Does the Cleanup Stack Work? 35 (3)
Using the Cleanup Stack with Non-CBase 38 (6)
Classes
Using TCleanupItem for Customized Cleanup 44 (2)
Portability 46 (1)
An Incidental Note on the Use of Casts 46 (1)
Summary 47 (2)
Two-Phase Construction 49 (6)
Descriptors: Symbian OS Strings 55 (20)
Non-Modifiable Descriptors 56 (2)
Modifiable Descriptors 58 (2)
Pointer Descriptors 60 (3)
Stack-Based Buffer Descriptors 63 (2)
Heap-Based Buffer Descriptors 65 (4)
Literal Descriptors 69 (3)
Summary 72 (3)
Good Descriptor Style 75 (16)
Descriptors as Parameters and Return Types 75 (3)
Common Descriptor Methods 78 (4)
The Use of HBufC Heap Descriptors 82 (2)
Externalizing and Internalizing 84 (2)
Descriptors
The Overuse of TFileName 86 (1)
Useful Classes for Descriptor Manipulation 87 (1)
Summary 88 (3)
Dynamic Arrays and Buffers 91 (20)
CArrayX Classes 92 (5)
RArray and 97 (5)
RPointerArray
Why Use RArray Instead of CArrayX? 102 (1)
Dynamic Descriptor Arrays 103 (1)
Fixed-Length Arrays 104 (2)
Dynamic Buffers 106 (3)
Summary 109 (2)
Event-Driven Multitasking Using Active 111 (16)
Objects
Multitasking Basics 111 (1)
Event-Driven Multitasking 112 (3)
Working with Active Objects 115 (5)
Example Code 120 (3)
Threads Without an Active Scheduler 123 (1)
Application Code and Active Objects 123 (1)
Summary 124 (3)
Active Objects under the Hood 127 (24)
Active Object Basics 128 (3)
Responsibilities of an Active Object 131 (2)
Responsibilities of an Asynchronous 133 (1)
Service Provider
Responsibilities of the Active Scheduler 134 (1)
Starting the Active Scheduler 135 (1)
Nesting the Active Scheduler 135 (1)
Extending the Active Scheduler 136 (1)
Cancellation 137 (1)
Request Completion 138 (1)
State Machines 138 (5)
Long-Running Tasks 143 (3)
Class CIdle 146 (2)
Class CPeriodic 148 (1)
Common Mistakes 149 (1)
Summary 150 (1)
Symbian OS Threads and Processes 151 (16)
Class RThread 152 (3)
Thread Priorities 155 (2)
Stopping a Running Thread 157 (5)
Inter-Thread Data Transfer 162 (1)
Exception Handling 163 (1)
Processes 164 (2)
Summary 166 (1)
The Client--Server Framework in Theory 167 (22)
Why Have a Client--Server Framework? 168 (1)
How Do the Client and Server Fit Together? 168 (2)
How Do the Client and Server Communicate? 170 (1)
What Classes Does the Client--Server 170 (9)
Framework Use?
How Do Synchronous and Asynchronous 179 (1)
Requests Differ?
How Is a Server Started? 179 (1)
How Many Connections Can a Client Have? 180 (1)
What Happens When a Client Disconnects? 180 (1)
What Happens If a Client Dies? 181 (1)
What Happens If a Server Dies? 181 (1)
How Does Client--Server Communication Use 181 (1)
Threads?
What Are the Implications of Server-Side 182 (1)
Active Objects?
What Are the Advantages of a Local 182 (1)
(Same-Process) Server?
What Are the Overheads of Client--Server 183 (3)
Communication?
How Many Outstanding Requests Can a 186 (1)
Client Make to a Server?
Can Server Functionality Be Extended? 186 (1)
Example Code 186 (1)
Summary 187 (2)
The Client--Server Framework in Practice 189 (28)
Client--Server Request Codes 190 (1)
Client Boilerplate Code 191 (7)
Starting the Server and Connecting to It 198 (5)
from the Client
Server Startup Code 203 (2)
Server Classes 205 (8)
Server Shutdown 213 (1)
Accessing the Server 214 (1)
Summary 214 (3)
Binary Types 217 (16)
Symbian OS EXEs 217 (1)
Symbian OS DLLs 218 (2)
Writable Static Data 220 (3)
Thread-Local Storage 223 (3)
The DLL Loader 226 (1)
UIDs 226 (2)
The targettype Specifier 228 (2)
Summary 230 (3)
ECOM 233 (14)
ECOM Architecture 233 (3)
Features of an ECOM Interface 236 (1)
Factory Methods 237 (3)
Implementing an ECOM Interface 240 (2)
Resource Files 242 (3)
Example Client Code 245 (1)
Summary 246 (1)
Panics 247 (8)
Just-In-Time Debugging 248 (1)
Good Panic Style 249 (1)
Symbian OS Panic Categories 250 (1)
Panicking Another Thread 251 (2)
Faults, Leaves and Panics 253 (1)
Summary 253 (2)
Bug Detection Using Assertions 255 (10)
__Assert_Debug 256 (5)
__Assert_Always 261 (2)
Summary 263 (2)
Debug Macros and Test Classes 265 (12)
Heap-Checking Macros 265 (5)
Object Invariance Macros 270 (3)
Console Tests Using RTest 273 (3)
Summary 276 (1)
Compatibility 277 (16)
Forward and Backward Compatibility 278 (1)
Source Compatibility 279 (1)
Binary Compatibility 280 (1)
Preventing Compatibility Breaks 281 (6)
What Can I Change Without Breaking Binary 287 (2)
Compatibility?
Best Practice: Planning for Future Changes 289 (2)
Compatibility and the Symbian OS Class 291 (1)
Types
Summary 292 (1)
Thin Templates 293 (6)
Expose a Comprehensive and Comprehensible 299 (18)
API
Class Layout 300 (1)
Import_C and Export_C 301 (2)
Parameters and Return Values 303 (6)
Member Data and Functional Abstraction 309 (3)
Choosing Class, Method and Parameter Names 312 (2)
Compiler--Generated Functions 314 (1)
Summary 315 (2)
Good Code Style 317 (16)
Reduce the Size of Program Code 317 (3)
Use Heap Memory Carefully 320 (5)
Use Stack Memory Carefully 325 (3)
Eliminate Sub-Expressions to Maximize 328 (2)
Code Efficiency
Optimize Late 330 (1)
Summary 331 (2)
Appendix Code Checklist 333 (6)
Glossary 339 (8)
Bibliography and Online Resources 347 (4)
Index 351
posted by シンビアン at 21:28| Comment(0) | TrackBack(0) | NOKIA SMARTPHONE HACKS | このブログの読者になる | 更新情報をチェックする

継承(「is a」の関係)

継承とは、あるクラスが別のクラスの「特化」であるという概念だ。継承の目的は、複数の派生(サブ)クラスの共通要素を規定する基底(スーパー)クラスを定義して、コードを単純にすることである。共通要素としては、ルーチンのインターフェイス、実装、メンバデータ、データ型などが挙げられる。継承を利用すれば、コードやデータを基底クラスで一元的に管理できるようになるので、複数の場所で定義する必要がなくなる。継承を使用する際には、次の点について決断する必要がある。

*

メンバルーチンはそれぞれ派生クラスから参照できるか。既定の実装を持つか。既定の実装はオーバーライド可能か。
*

メンバデータ(変数、名前付き定数、列挙など)はそれぞれ派生クラスから参照できるか。
posted by シンビアン at 20:50| Comment(0) | TrackBack(1) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

プライベート継承を使って「has a」を実装するのは最後の手段である

状況によっては、あるオブジェクトを別のオブジェクトのメンバにする方法では、包含を実現できないことがある。そのような場合、一部の専門家は、包含されるオブジェクトをプライベートで継承することを提案している(Meyers1998; Sutter 2000)。そうする主な理由とは、含む側のクラスを含まれる側のクラスのprotectedのメンバルーチンまたはメンバデータにアクセスさせるためである。実際には、これでは祖先のクラスとの結合度が強くなりすぎて、カプセル化に違反してしまう。たいていは、プライベート継承以外の方法で解決しなければならない設計上のミスである。
posted by シンビアン at 20:39| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

確保したヒープメモリの有効範囲

質問:

[PIMInfo->PIMAplWork]に設定したヒープはOUT中でも保持されるとの事ですが、 それ以外のポインタ(外部変数)等に確保したヒープは保持されないのでしょうか?サンプルで実験したところでは、問題なく保持されているようです。

PTR pDummy;

BOOLEAN PIMAplConstruct(PIMINFO *PIMInfo, USHORT InitLevel)
{
/* OUTワークの確保 */
if (!(pDummy = NewHeapPtr(1000)))
{
/* ヒープが確保できない場合は − 続行不可能 */
return false;
}
return true;
}

この様な方法で確保したヒープメモリが保持できない理由と、メモリの内容が破壊されるタイミングを教えて欲しい。

回答:

ヒープ領域の有効範囲については、確保した関数は関係ありません。ヒープ領域自体はアプリケーションプロセスが起動している間中、保持されます。従いまして、確保した領域へのハンドル、またはポインタを格納する変数に依存します。
PIMInfo->PIMAplWorkは、アプリケーションプロセスが起動している間中、保持されます。
PIMExecWork->PIMUserWorkは、アプリケーションがアクティブな間中、保持されます。アプリケーションがOUT状態になった時点で値は保証されなくなります(通常はOUT状態に移行する前にユーザが解放する必要がありますが、仮に解放しなくても値は保証されません)。
AplForm->UserWorkはフォームが表示されている間中、保持されます。他のフォームに切り替わった時点で値は保証されなくなります(通常はフォームが切り替わる前にユーザが解放する必要がありますが、仮に解放しなくても値は保証されません)。
その他の、例えばお客様がご指摘されているような外部変数についてはC言語の仕様に準じます。つまり外部変数の場合は、アプリケーションプロセスが起動している間中、保持されます。
posted by シンビアン at 20:12| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

ヒープメモリについて

1)PIMクラスメソッドにおいて確保したヒープメモリの有効範囲
PIMAplSetupにおいてNewHeapPtrで確保したヒープメモリは、アプリケーション上でいつでも使用する事が可能か? 一度OUT状態になっても再びEXEC状態に戻れば、ヒープメモリが開放されたりメモリの内容が破壊されたりする事は無いと考えて良いか?

(2)この様にアプリケーションが常時使用するヒープメモリは、PIMAplConstructとPIMAplSetupのどちらで確保した方が良いのか?

(3)PIMクラスメソッドにおいて確保したヒープメモリの開放処理
 PIMAplConstruct又はPIMAplSetupで確保したヒープメモリを開放する場合は、PIMAplEndで行う必要があるか? それともOSに任せて、開放処理を行わない方が良いのか?

回答:

(1)OUT中でも保持されています。
ここでいうOUT中も保持されるヒープとは[PIMInfo->PIMAplWork]に設定したヒープです。

(2)どちらでも結構ですが、プログラミングガイド第8章のサンプルでは、PIMAplConstruct関数で確保しています。

(3)これらの関数内で確保すべき、OUT中も保持されるヒープの解放は、アプリ終了時にシステムが行います。ユーザーが解放する必要はありません。なお、ここでいうOUT中も保持されるヒープとは[PIMInfo->PIMAplWork]に設定したヒープです。


アプリケーションで使用する上記のようなヒープは、大まかに3種類あります。下記以外にも局所的に使用するワークとしてのヒープもあります。

・OUT中も内容が保持されるヒープ
 PIMAplConstruct または PIMAplSetUp関数で[PIMInfo->PIMAplWork]に設定したヒープです。主にレジュームするための情報を保持しておきます。ユーザーが解放処理をする必要はありません。

・EXEC中に保持されているヒープ(OUT中は不明)
 PIMExecConstruct または PIMExecSetUp関数で[PIMExecWork->PIMUserWork]に設定したヒープです。主に複数のフォーム間で共有する情報を保持しておきます。ユーザーがPIMExecEnd関数で解放処理を行います。

・フォーム実行中に保持されているヒープ(フォーム終了後は不明)
 FormConstruct または FormSetUp関数で[AplForm->UserWork]に設定したヒープです。主にフォーム実行中に参照したい内容を保持しておきます。ユーザーがFormEnd関数で解放処理を行います。
posted by シンビアン at 20:11| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

ヒープメモリ

Microsoft IEで不正なCSSタグを解析するとヒープメモリがクラッシュする脆弱性が見つかる
サイバーディフェンス社からの情報によると、マイクロソフト社のInternet Explorerの複数のバージョンで、リモートから攻撃可能なバッファオーバーフローが見つかった。これにより、ローカルユーザの権限で任意のコードが実行される可能性がある。この問題は、CSS(Cascading Style-Sheets)を処理する際の不正なバッファが原因で発生する。@;/*というCSSスタイルタグを含んだ不正なwebページを表示させられると、脆弱なバージョンのIEがクラッシュする可能性がある。この脆弱性により、任意のコードが実行される可能性がある。
posted by シンビアン at 20:10| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

2006年01月31日

第13章 constオブジェクト

今回は、constオブジェクトについて解説します。 constとは、読んで字のごとく「定数」という意味です。これは、勝手に値を変更できないことを意味しています。したがって、オブジェクトをconstで宣言するとデータメンバは、一切変更できなくなります。それどころかメンバ関数も一切呼び出せなくなります。もしかすると、メンバ関数が値を書き換えようとするかもしれないからです。
エー、そりゃ大変だな・・・
ま、例題プログラムを見てみましょう。

#include class Test { public: int a; Test(); ~Test(); int show(); }; Test::Test(void) { cout << "数値を入力-- "; cin >> a; } Test::~Test() { cout << "デストラクタが呼ばれました。\n"; } int Test::show(void) { cout << "[show] a = " << a << endl; return 0; } int main(void) { const Test x; cout << "[main] x.a= " << x.a << endl; //x.a = 20; エラーとなります。 //x.show(); 呼び出せません。 Test y; cout << "[main] y.a= " << y.a << endl; y.a += 12; //constオブジェクトでないので大丈夫 y.show(); cout << "値を変更しました。y.a = " << y.a << endl; return 0; }

オブジェクトxはconst宣言をしているのでデータメンバa に、値を代入することはできません。また、show関数を呼び出すこともできません。

一方、オブジェクトbは、const宣言をしていませんからデータオブジェクトに代入したり、show関数を呼び出したりできます。

当たり前ですがconst宣言をしていてもデストラクタとか、コンストラクタは自動的に呼ばれます。

いくらconstオブジェクトでも、値を書き換えないようなメンバ関数まで呼び出せないのはつらい?ですね。そこで、メンバ関数の宣言時に関数の最後にconstと付け足してやります。こうすれば呼び出すことができます。また、このconstは関数定義の所でも必ず記述しなくてはいけません。ではサンプルプログラムを見てみましょう。

#include class ConstTest { public: int a; ConstTest(); void show() const; //constの位置に注意 }; ConstTest::ConstTest(void) { a = 100; } void ConstTest::show(void) const //ここにもconst必要! { cout << "show関数が呼ばれました" << endl; cout << "a = " << a << endl; return; } int main(void) { const ConstTest x; x.show(); return 0; }

はい、左のようにshow関数を呼び出すことができました。では、このshow関数中にこっそり値を書き換えるような記述をしたらどうでしょうか?
何で、そんな変なことをするんだ!?
はい。ばかばかしいことでも実際に実験してみることが大事です。

error C2166: const型で宣言された項目を修飾しようとしました。

筆者の処理系では上のようなエラーメッセージが出てコンパイルできません。みなさんの処理系ではどうですか?
posted by シンビアン at 19:28| Comment(1) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

開発環境をそろえる

SDKの入手


FORUM NOKIAのDeveloper GuideからツールSDKダウンロードを選んでSeries 60 SDK (ソフト開発キット) for Symbian OS Nokia Edition (英語)をクリックします
ここで、2nd ed.FP 2,japanies(141MB)を選んでDownload nowを押すとForum Nokiaのアカウント(IDとパスワード)を聞いてきますのでID,パスワードを入れてください。
このアカウントはthe registration form から登録できます。これは、簡単なアンケートです。
アンケート後に送られて来たメールでレジストしてください。
日本語版と英語版のメールが来ますが、英語版が来るまでダウンロードは出来ません。
あとは、別ウインドウでダウンロードが始まりますので、終了するのを待ってください。(私の環境ではダウンロード後にIEが異常終了しましたが、ダウンロードはちゃんとできました。

Perlの入手


このSDKではPerlが必要ですので、ActivePerlをインストールしておきます

JRE1.4の入手


無くてもコンパイルは出来ますが、ツールが一部使えませんのでJava Run-Timeの1.4以降をインストールして置いてください。

SDKのインストール


画面の指示に従ってインストールしてください。最後に再起動があります

VC,BloandC++を使わないでコンパイル


実は、エミュレータを使わなければこのIDE環境は不要です。
いきなり実機でのテストになりますが

HelloworldBasicをコンパイルしてみる


* Windowsのコマンドラインを開きます
* HelloworldBasicのディレクトリーにいどうします
CD \Symbian\8.0a\S60_2nd_FP2_J\Series60Ex\helloworldbasic\group
* ビルドの準備を行います
bldmake bldfiles
* ビルドします
abld build THUMB UREL
* ビルドが終了すると¥SISフォルダにpkgファイルがファイルができますので、SISファイルに変換します
CD \Symbian\8.0a\S60_2nd_FP2_J\Series60Ex\helloworldbasic\sis
makesis helloworldbasic.pkg
* これでSISファイルができましたので、超勝手アプリのインストールと同じように702NKへインストールします。

※ちなみに\Symbian\8.0a\S60_2nd_FP2_J\epoc32\BUILDの下にMakeファイル、オブジェクトが作成されますので気をつけてください

AIFのアイコンを変更するときは一度、\epoc32\data\Z\system\APPS\アプリケーション名\の下のAIFファイルを消して、再度BUILDします。
これをしないとアイコンが変更されません

これで何とか、開発できる状態になりましたので、実際のプログラムの構成を見て行きたいと思います。
posted by シンビアン at 18:31| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

Helloworldbasocを解析

ディレクトリ


ファイル


意味
aif helloworldbasicaif.rss リソース定義ファイル
  qgn_menu_demo_cxt.bmp アイコン用BitMAP 44x44
  qgn_menu_demo_cxt_mask.bmp アイコン用BitMAP(MASK)
  qgn_menu_demo_lst.bmp アイコン用BitMAP 42x29
  qgn_menu_demo_lst_mask.bmp アイコン用BitMAP(MASK)
data helloworldbasic.loc ローカル定義(文字列)
  helloworldbasic.rss menu用リソース
  helloworldbasic_caption.rss CAPTION用リソース
group ABLD.BAT bldmake filesで作成されたバッチファイル
  bld.inf bldmake用定義ファイル
  helloworldbasic.mmp bld用プロジェクトファイル
inc helloworldbasic.hrh コマンドコード
  helloworldbasic.pan panic codes
  helloworldbasicapplication.h CHelloWorldBasicApplicationクラス(CAknApplication)
  helloworldbasicappui.h CHelloWorldBasicAppUiクラス(CAknAppUi)
  helloworldbasicappview.h CHelloWorldBasicAppViewクラス(CCoeControl)
  helloworldbasicdocument.h CHelloWorldBasicDocumentクラス(CAknDocument)
sis helloworldbasic.pkg SIS作成用ファイル(ABLDで生成)
  helloworldbasic.SIS makesisで作成
src helloworldbasic.cpp 本体(Applicationクラスを呼び出す)
  helloworldbasicapplication.cpp アプリケーションクラス(ドキュメントの作成とUIの呼び出し)
  helloworldbasicappui.cpp UIクラス(Viewクラスの呼び出しとコマンドの処理)
  helloworldbasicappview.cpp ウインドウの生成と画面の線画
  helloworldbasicdocument.cpp Docuemntクラス、この場合はドキュメントの処理は無し、UIの生成のみ

これで、大体の構成はわかったような気がします
posted by シンビアン at 18:26| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

コード変換

TBool CBTMSG60AppView::CharConvertL(TInt aTargetCode, TDes & aDes) const
{
TBuf unicodeMessage;
TBuf8 jiscodeMessage;

unicodeMessage.Copy(aDes);

CCnvCharacterSetConverter* converter = CCnvCharacterSetConverter::NewLC();
if(converter->PrepareToConvertToOrFromL(aTargetCode,
iEikonEnv->FsSession()) != CCnvCharacterSetConverter::EAvailable)
User::Leave(KErrNotSupported);

if(CCnvCharacterSetConverter::EErrorIllFormedInput == converter->ConvertFromUnicode(jiscodeMessage, unicodeMessage))
User::Leave(KErrArgument); //Leave if error in conversion.

aDes.Copy( jiscodeMessage );

return ETrue;

}



呼び出すときは

iAppView->CharConvertL(KCharacterSetIdentifierShiftJis, textData);

って感じで。他の漢字コードを使いたいときは一つ目の引数を変える。charconv.h charconv.lib も忘れずに!!
posted by シンビアン at 18:20| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

エディタの入力モードを変更したい

RESOURCE DIALOG r_dataquery_data_query
{
flags=EGeneralQueryFlags;
buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
items =
{
DLG_LINE
{
type = EAknCtQuery;
id = EDataQueryDlgCIdDataQuery;
control = AVKON_DATA_QUERY
{
layout = EDataLayout;
control =
EDWIN
{
avkon_flags = EAknEditorFlagLatinInputModesOnly;
width = KMaxCommandNameLength;
lines = 1;
maxlength = KMaxCommandNameLength;
};
};
}
};
}
posted by シンビアン at 18:18| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

プログラミング

# サンプルプログラムのビルド(エミュレータ)

全てのプログラミングの習得についていえることですが、「習うより慣れろ」が大きいと思います。幸い、SDKにはたっぷりのサンプルが付いていますのでこれを活用します。自分の希望に近いサンプルを見つけたら、コマンドプロンプトを起動して下記のコマンドを実行してみましょう。

* cd "C:\Symbian\8.0a\S60_2nd_FP2_J_B\Series60Ex\APP_NAME\group"
* bldmake bldfiles
* abld build wins udeb

ここまでで、エミュレータで動作するビルドが出来ました。エミュレータを起動して動作を確認してみましょう。

# IDE ターゲット用のビルド

* abld makefile vc6

"C:\Symbian\8.0a\S60_2nd_FP2_J_B\epoc32\BUILD\SYMBIAN\8.0A\S60_2ND_FP2_J_B \SERIES60EX\APP_NAME\"以下(設定により若干変わることあり)に VC6 の設定ファイル (*.dsw) が出来ます。これをダブルクリックして VC6 の IDE 環境でデバッグすることが出来ます。
posted by シンビアン at 17:20| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

UID

UID とは Symbian OS 上で動作するアプリケーションを特定するための ID です。各アプリケーションが一意の ID 保持しています。自作アプリの外部公開を目指す人はこの UID を取得する必要があります。uid AT symbiandevnet.com にメールで問い合わせます。
posted by シンビアン at 17:19| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

エミュと実機のビルド

エミュと実機でビルドの条件を少しだけ変えたい場合は以下のようにする。(NextTrain60 から引用)

#if __WINS__
_LIT(KTbls, "C:\\nexttrain60\\tbls\\");
#else
_LIT(KTbls, "E:\\nexttrain60\\tbls\\");
#endif

エミュレータのときは "_LIT(KTbls, "C:\\nexttrain60\\tbls\\");" がコンパイルされる。
posted by シンビアン at 17:15| Comment(1) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。