netbeansを使ったs60向けJavaアプリ開発環境の導入
netbeansでのs60向けMIDPアプリの開発は、PCSuite経由で接続さえされていれば
BT,USB,IRなどインターフェイス問わず実機デバッグできたりとすごく便利です。
世の中あいほんやあんどろいど一色なのでまったく需要が無さそうですが
メモっておかないと後で自分が困りそうなので書いておきます。
ちなみに今回は、自分が持っているN82を対象にするので
以下の記述はs60v3 FP1向けの記述になります。
FP2端末の場合などは、SDKのダウンロード辺りを適当に読み替えれば何とかなると思います
netbeansにs60SDKを認識させる
1.NetBenas 6.7をインストール
2.プラグインのカテゴリ「Java」から、Mobilityをインストール
(これでJ2ME開発ができるようになる)
3.Forum Nokiaから「s60v3 FP1 SDK for Java」をダウンロードしてインストール
(解凍した中にあるnetbeans_documentation_setupは無視していい)
4.このままだとエミュレータの分析ツールが起動できないので、
「C:\S60\devices\S60_3rd_MIDP_SDK_FP1\bin\epoc32\tools\ecmt\config\config.properties」の一行に1.6,6.0と追記
(JDK6でも動くように書き換え)
- epdt.java.version.start=1.4.1,1.4.2,1.5,5.0 + epdt.java.version.start=1.4.1,1.4.2,1.5,5.0,1.6,6.0
5.スタートメニューにあるs60 Developer Toolsの中にあるエミュレータがきちんと起動できることを確認する。
ここで、エミュレータのPreferencesを選択した際に「Cannot start ECMT Manager」と出る場合は、4がきちんと出来ているか確認する。
6.netbeansの新規プロジェクトからJ2ME->モバイルアプリケーション->SDK/プラットフォーム/エミュレータをインストールをクリック
7.プラットフォームを追加->Java ME MIDP プラットフォームエミュレータをクリック
8.エクスプローラで場所を指定することになるので、C:\S60などエミュレータをインストールした付近のディレクトリを選択すると、エミュレータが検出される。
9.新規プロジェクト作成後に、「プロジェクト構成の追加」から「インストールしたCLDCプラットフォームが提供する構成テンプレート」を選択
この中にS60Emulator,S60Deviceと二つ構成があるので両方とも追加する。
エミュレータ上で動かしたい場合はそのまま構成をS60Emulatorとする。
実機でのデバッグ環境構築
1.PCSuiteで「C:\S60\devices\S60_3rd_MIDP_SDK_FP1_3\s60tools\Ecmt\EcmtAgent_MIDP.SIS」を端末にインストールする
2.端末にインストールされたDebugAgentを起動しておく
3.「C:\S60\devices\S60_3rd_MIDP_SDK_FP1_3\bin\epoc32\tools\ecmt\ecmtgw.exe」にあるDevice Connectivity Toolを起動して
Commentの欄がEcmtAgentになっているものと選んでconnectする。
(PC Suiteで接続している端末であれば検知可能)
ここまで出来たら、ターゲットを「S60Device」にしてビルドすると、自動的に実機に転送されてデバッグが可能。
普通にブレークポイントを掛けたりすることもできる。
実機でデバッグ中のモニタリング
Device Connectivity Toolのメニューからdiagnosticsを選ぶと、接続中の端末の
CPU使用率/メモリー使用率/動作中のアプリケーション別のCPU使用率/各ドライブの残容量/ネットワーク使用率をリアルタイムに観察できる。
作成したアプリケーションのデプロイ
1.プロジェクトのプロパティから「配備」->配備メソッドを選択の欄を「PC Suite経由で接続されたNokia端末」に変更
2.netbeansメニューのツール->「Mobilityの配備」から、「PC Suite経由で接続されたNokia端末」を選ぶと、
現在PC Suiteで接続されている端末の一覧が出るので、デプロイしたい端末をここで選択。
設定を終えれば、プロジェクトを右クリックから「配備」を選ぶと、端末に.jarが送られるので
あとは端末側でいつも通りインストールするとワンクリックでデプロイできる。
トラブルシューティング
ConnectivityToolから接続までできているのにnetbeansのconnect Agentで止まる場合
間違ってFP2用のDebugAgentをインストールすると、うまくconnectできない。
diagnosticsのBT通信ログを見て変なエラーコードが端末から帰ってきてたらこれ
とりあえず今のところこれぐらい。また追記するかも
コンストラクタの明示的呼び出し
VCでは
#include <iostream> class A { public: A(int i) : m_i(i){} A(const A& obj) : m_i(obj.m_i){} int m_i; }; int main() { A a(10); std::cout << a.m_i << std::endl; a.A::A(20); std::cout << a.m_i << std::endl; A b(30); a.A::A(b); std::cout << a.m_i << std::endl; return 0; }
こんな感じにコンストラクタを明示的に呼べるので、そういうもんだと思ってたんだけど
どうやら規格ではこれは禁止されているらしい。
試しにgccとcomeau C++(online ver)でためしてみたところ
//gcc4.3.2(cygwin) ArgTest.cpp: In function 'int main()': ArgTest.cpp:15: error: invalid use of 'class A' ArgTest.cpp:18: error: invalid use of 'class A'
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors C++ C++0x_extensions "ComeauTest.c", line 15: error: a constructor or destructor may not have its address taken a.A::A(20); ^ "ComeauTest.c", line 18: error: a constructor or destructor may not have its address taken a.A::A(b); ^ 2 errors detected in the compilation of "ComeauTest.c".
ってなった。
要するにおとなしくplacement newしとけって話ですね。
ポインタ型宣言時の書き方について
この前どこかでポインタ型宣言の書き方が
int* a;//C++な人 int *b;//Cな人
になってること多いよね。みたいなエントリを見たのでちょっとこれについて。
(たぶんRSSリーダーかtwitterのリンクから飛んだんだけど消息不明に。知ってる人いたらアドレス教えて)
まず、ポインタ型の宣言の仕方について、ちょっと前までは自分も
int* a;
みたいな感じに書いてました。
根拠としては単純に「int*型のaを宣言する」って見方ができるのでいいなってことだったんだけど、
この理解の仕方には微妙に問題があったり。
というのも、例えば下のようなコードを書いたときに
class Test { }; int main() { Test* pa,pb; pa = new Test; pb = new Test;//pbはTest*型ではなくTest型なのでコンパイルエラー return 0; }
みたいな事が起きる。
この程度のものならすぐに発見できるのでいいんですが、
テンプレートとかを使ったコードを書いているときにこの手のものに遭遇すると
変な特殊化が行われたりと割とひどい目にあったりします。
なので最近は、
「int*型の変数aを宣言する」ではなく
「*aするとint型になるポインタaを宣言する」
っていう理解で変数側に*を付ける派に転向したり。
まあこの辺は個人の趣味もあるのでなんとも言えないですが。
コンパイラ電卓
すごく実用性のないものを作った
#include <iostream> //a + b template <int a,int b> struct Adder { enum {value = a + b }; }; //num! template <int num,int unused> struct Factor { enum {value = num * Factor<num - 1,unused>::value}; }; template <int unused> struct Factor<0,unused> { enum {value = 1}; }; template <int num,int power> struct Power { enum {value = num * Power<num,power - 1>::value}; }; template <int num> struct Power<num,0> { enum {value = num}; }; //a % b template <int a,int b> struct Remainder { enum {value = A % B}; }; //a / b template <int a,int b> struct Divide { enum {value = a / b}; }; //a * b template <int a,int b> struct Multiple { enum {value = a * b}; }; int main() { #ifndef A #define A 1 #endif #ifndef B #define B 1 #endif std::cout << STAT<A,B>::value; return 0; }
コンパイル時にマクロで引数を与えてやると
c:\Users\hiroya\Documents\Visual Studio 2008\Projects\TestProject>cl main.cpp -D STAT=Adder -DA=1 -DB=2 Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. main.cpp C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\xlocale(342) : warning C 4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効にはなりま せん。/EHsc を指定してください。 Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:main.exe main.obj c:\Users\hiroya\Documents\Visual Studio 2008\Projects\TestProject>main.exe 3 c:\Users\hiroya\Documents\Visual Studio 2008\Projects\TestProject>cl main.cpp -D STAT=Power -DA=2 -DB=5 Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. main.cpp C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\xlocale(342) : warning C 4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効にはなりま せん。/EHsc を指定してください。 Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:main.exe main.obj c:\Users\hiroya\Documents\Visual Studio 2008\Projects\TestProject>main.exe 64
ちなみに、アセンブラファイルを出力させてみると
; 1035 : std::cout << STAT<A,B>::value; 00003 6a 40 push 64 ; 00000040H 00005 8b 0d 00 00 00 00 mov ecx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A 0000b ff 15 00 00 00 00 call DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z
ということで、生成される実行ファイルはちゃんと定数をpushするだけになってる。
もともとはsinとかcosとかをコンパイル時に実行できたらいいなと思って書いていたので、
↓みたいなものも書いてたんだけど
template <double num,int recursionCount> struct Sin { enum {value = Sin<num,recursionCount - 1>::value + (!recursionCount) * (1 / (Factor<recursionCount * 2 + 1,1>::value)) * Power<num,recursionCount * 2 + 1>::value}; }; template <double num> struct Sin<num,0> { enum {value = num}; };
書き終わってから、「コンパイル時に小数って普通にやったら駄目なんじゃないの」ってことに気づいてみたり。
なので上のコードは一度も実行してないというか、できないというか、デバッグもできてないしもしかしたら再帰がとまらないかもしれない。
どうやらコンパイル時に小数を扱うのは、Boost/MPLにちょっとあるみたいなんだけど、実装ほぼ空だった。
BoostVaultにはもうちょっとましなのがあるらしいので、試してみようかな。
最初からついてた液晶保護シールを剥がした
N82に最初からついてた液晶保護用のシールがはがれ始めたので剥がしてみたら
元々液晶の部分がフラットなデザインなのでだいぶいい感じになった。
まあ液晶にひどい傷でもできたら液晶カバーを2000円ぐらいで交換すれば良さそうなので
保護シールとかはつけずにこのまま使おう。