ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示

2010/08/08

2010/07/07

ついっぷるとOsfooraでつぶやくiPad用ブックマークレット

ブラウザで見ているページのタイトルとURLをつぶやくためのブックマークレット

  • ついっぷる(Webアプリ版)でつぶやく
javascript:window.location='http://twipple.jp/login?text=Now%20Browsing:%20'+encodeURIComponent(document.title+'%20'+window.location)

  • Osfooraでつぶやく
javascript:window.location='osfoora://Now%20Browsing:%20'+encodeURIComponent(document.title+'%20'+window.location)

2010/03/05

VC#でFXアプリを作成する …マネックスJooトレーディングAPIをプロジェクトに追加

忘れないようにメモ。

Visual C#のプロジェクトでマネックスJooトレーディングAPIを利用出来るようにした際の手順です。

  1. 「プロジェクト」― 「参照の追加」を選択して「参照の追加」ダイアログを開く
  2. 「参照」タブを開く
  3. 「C:\Program Files\マネックスJooトレーディングAPI」フォルダを開いて「Joo.FXAPI.dll」を選択し、「OK」ボタンを押す
  4. 「ソリューションエクスプローラ」の「参照設定」に「Joo.FXAPI」が追加されたことを確認する


これでForm1.csを以下のように記述したプロジェクトのビルドができました。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Joo.FXAPI.Entity;
using Joo.FXAPI.Service;

namespace TYFX
{
public partial class Form1 : Form
{
private ComApi api = null;

public Form1()
{
InitializeComponent();
api = new ComApi();
}
}
}

2009/07/23

iPhoneアプリ作成:テーブルビューセルのサンプルアプリが落ちる

SoftBank Creativeの「はじめてのiPhoneプログラミング」のサンプルアプリを作成しながら悩んだことのメモです。

いろいろ悩んでます。


P.223「UITableViewCellのカスタムサブクラス」から始まるサンプルの作成で、Cellsアプリが実行時に不正に終了してしまい困りました。

ブレークしながら実行すると、以前悩んだときと同じように"EXC_BAD_INSTRUCTION"と表示されます。


この本のサイトから取得したサンプルソースを参照したところ、iPhone SDK 2.1以上を使用している場合に変えなければならない所があるみたいです。
Jeff and Dave's Excellent iPhone Support Page


- tableView:cellForRowAtIndexPathメソッドにおいて、本の文中では次のようにあります。
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:1];


これの[nib objectAtIndex:1]としている箇所を次のように[nib objectAtIndex:0]にしなければならないようです。

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];



サンプルソースでは、コメントで次のように記述されています。
The behavior here changed between SDK 2.0 and 2.1. In 2.1+, loadNibNamed:owner:options: does not include an entry in the array for File's Owner. In 2.0, it does.




難しいです。

iPhoneアプリ作成:UITableViewCell で「warning: 'setText:' is deprecated」

SoftBank Creativeの「はじめてのiPhoneプログラミング」のサンプルアプリを作成しながら悩んだことのメモです。

ちびちびとやってます。


iPhone SDK 3.0 を使用したビルド環境でテーブルビューを使うサンプルアプリを作成すると、警告が出てしまうところがあります。

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];

〜省略〜

NSUInteger row = [indexPath row];
cell.text = [listData objectAtIndex:row];

上記のコードのうち、
cell.text = [listData objectAtIndex:row];
で次のような警告が出ます。
warning: 'setText:' is deprecated



UITableViewCellクラスのドキュメントを見ると下記のようにあります。
text

The text of the cell. (Deprecated. Use the textLabel and detailTextLabel properties instead.)


ネットで調べたところiPhone SDK 3.0で"Deprecated"になったようです。


どのように変更するのがいいのかAppleのiPhone Reference Libraryで検索してみたところ、次のようにしているサンプルコードがありました。
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@"CellWithSwitch"];

〜 省略 〜

cell.textLabel.text = @"Sound Effects";


これにならい次のように変更したところ、警告が出なくなったようです。
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];

〜省略〜

NSUInteger row = [indexPath row];
// cell.text = [listData objectAtIndex:row];
cell.textLabel.text = [listData objectAtIndex:row];



ビルド後に実行してみても意図した通りの動きをするようなので、大丈夫なんでしょう。
多分。

2009/07/19

iPhoneアプリ作成:Picker Viewがおかしなことに…

SoftBank Creativeの「はじめてのiPhoneプログラミング」のサンプルアプリを作成しながら悩んだことのメモです。

相変わらずよく分からずにやってます。

Picker Viewをつかったサンプルアプリの表示がおかしなことになってしまいました。
ピッカーの項目がビュー全体に広がってしまいました。


Picker Viewを使ったnibをInterface Builderで開き、File's Ownerを選択してコネクションインスペクタを開いたところ、アウトレットのところでviewがPickerに結びついてしまっています。


次のようにviewをViewに結びつけるように変更しました。



そしてビルドし直して実行します。



問題なくなったようです。



しかし、なんでこんなことに…。

iPhoneアプリのデバッグ中にEXC_BAD_INSTRUCTIONで落ちて困った

SoftBank Creativeの「はじめてのiPhoneプログラミング」のサンプルアプリを作成しながら悩んだことのメモです。

相変わらずマヌケなことやってます。


アプリの起動直後に異常終了してしまって困りました。

Xcodeのウィンドウの下の方には"EXC_BAD_INSTRUCTION"と表示されます。


デバッガの使い方もよく分かっていないのですが、デバッガでブレークポイントを設定してブレークしながら実行していると、"EXC_BAD_INSTRUCTION"表示されます。

ブレークしないで実行しても、アプリが落ちるだけでXcode側には特に何も表示されません。

まだまだ覚えなければならないことが多そうです。


"EXC_BAD_INSTRUCTION"についてですが、どうやらアウトレットの接続ミスのようです。

以下のサイトを参考にさせていただきました。
iPhone SDK APP STORE公開までのアプリ開発まとめ。遥か遠い環境設定と開発の道。


Xcodeでアウトレットを作成した際、アウトレット変数の名前をdatePickerとすべきところをdataPickerにしてしまいました。
IBOutlet  UIDatePicker  *dataPicker;


アウトレット変数の名前を間違えたままInterface Builderでアウトレットを使用してしまいました。



その後アウトレット変数の名前を間違えたことに気付き、Xcodeでソースは下記のように修正しました。
IBOutlet  UIDatePicker  *datePicker;


しかし、Interface Builderの方は修正をせず、悪いことに修正をしなくてもビルドが通ってしまい、実行時に"EXC_BAD_INSTRUCTION"のエラーが発生してしまったようです。


我ながらお恥ずかしい限りです。

2009/07/17

「はじめてのiPhoneプログラミング」の第5章「Swap」が実行時エラーになって困った

SoftBank Creativeの「はじめてのiPhoneプログラミング」のサンプルアプリを作りながら勉強しています。

「第5章 オートローテーションとオートサイジング」の後半で作っている「Swap」が実行時にエラーになってしまって困りました。

我ながらアホなことをやったみたいですが、どうやらP.118「2つのビューをデザインする」で作成する2つのビューの作り方が悪かったようです。

この書籍のネットで配布されているサンプルプログラムをダウンロードして、それを調べて気づいたのですが、PortraitとLandscapeのどちらのビューにも「view」アウトレットを結びつけていなかったのが原因のようです。


Portraitビューの方に以下のように「view」アウトレットを結びつけたら無事起動するようになりました。



本文中に下記のように記述されているところを間違えたみたいです。
では、File's OwnerアイコンからPortraitアイコンまでコントロール—ドラッグして、灰色のメニューがポップアップしたら、portraitアウトレットを選択します。それから、またFile's Ownerを今度はLandscapeアイコンにコントロ—ル—ドラッグして、Viewアウトレットを選択し、起動時にどちらのビューが表示されるかを指示します。

2009/05/29

Java: Generics (型を"<"と">"で囲んで指定する)

最近覚えたJavaのすごく基本的なことのメモです。
勉強不足です。

new演算子でオブジェクトを作成する際に、クラスの後ろに"<"と">"に囲まれて型を指定する
→ J2SE5.0から新しく導入されたGenericsと呼ばれる機能

ワイルドカード"?"も使えるらしい。

以下、参考にしたサイトです。

ArrayListクラス - コレクション(ArrayList) - Java入門 [www.javadrive.jp]
- Java Generics概説 [www.objectclub.jp]

2009/05/27

Android: Antでビルド時に文字コードがらみの警告?

@ITのチュートリアルをやっています。
AndroidでSQLiteのDB操作をするための基礎知識 (1/3) - @IT [www.atmarkit.co.jp]

SQLiteを使用する回のサンプルプログラムをダウンロードして以下の手順でプロジェクトをアップデートした後、CUI環境でコンパイルしようとしました。

ビルド環境:
  • WindowsXP にインストールしている Portable Ubuntu for Windows


・プロジェクトをアップデート
$ android update project \ 
> --name "DB Demo" \
> --target 2 \
> --path $PWD


ant debugでビルドしてみると、文字コードがらみらしい警告が多量に発生し、ビルドもとおりません。
以下のログは文字化けしている箇所は"文字化けした文字列"と置き換えています。

・プロジェクトのビルド
$ ant debug
Buildfile: build.xml
[setup] Project Target: Android 1.5
[setup] API level: 3

dirs:
[echo] Creating output directories if needed...

(省略)

[javac] /mnt/D/xxx/workspace/DB_Demo3/src/com/example/android
/db/Main.java:87: 警告:この文字は、エンコーディング ascii にマップできません。
[javac] {"文字化けした文字列"},
[javac] ^
[javac] /mnt/D/xxx/workspace/DB_Demo3/src/com/example/android
/db/Main.java:87: 警告:この文字は、エンコーディング ascii にマップできません。
[javac] {"文字化けした文字列"},

(省略)

[javac] /mnt/D/xxx/workspace/DB_Demo3/src/com/example/android
/db/Main.java:232: エスケープ文字が不正です。
[javac] {"文字化けした文字列"},
[javac] ^
[javac] エラー 1 個
[javac] 警告 100 個

BUILD FAILED
/home/pubuntu/bin/android-sdk/platforms/android-1.5/templates
/android_rules.xml:116: Compile failed; see the compiler error output for details.

Total time: 12 seconds


どうやら日本語の文字列が含まれたファイルで警告が出ているようです。
警告が出ているファイルを調べると、Shift JISでした。

試しにUTF-8に変換してみたところ、警告が大量に出るのは変わらなかったのですが、ビルドは成功しました。
しかし、Android Dev Phone 1(ADP1)にインストールして起動してみたところ、起動時にエラーとなりこのサンプルアプリケーションを使用することはできませんでした。

ネットで調べてみたのですが、通常のJavaであればAntでnative2asciiを使うとか色々引っかかりましたが、なかなかAndroidの情報が見つかりません。
同様にnative2asciiを使用してみようかと思ったのですが、挫折しました。


やっとAndroid の build.xml のサンプルが見つかりましたので、これを参考にbuild.xmlをいじってみました。

はっきり言って意味は分かっていません。
エラー -> 修正 を繰り返して以下のコードにおちつきました。
もうちょっと調べてみたいと思います。

・build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="DB Demo" default="help">

(省略)

<target name="compile" depends="dirs, resource-src, aidl">
<javac encoding="SJIS" target="1.5" debug="true" extdirs=""
srcdir="."
destdir="bin/classes"
bootclasspath="${sdk-location}/platforms/android-1.5/android.jar">
<classpath>
<fileset dir="libs" includes="*.jar"/>
</classpath>
</javac>
</target>
</project>

build.xmlの末尾の</project>の前に<target>〜</target>を追加しています。


build.xmlを修正後、再度ビルドします。
$ ant debug
Buildfile: build.xml
[setup] Project Target: Android 1.5
[setup] API level: 3

(省略)

[apkbuilder] Creating DB Demo-debug.apk and signing it with a debug key...
[apkbuilder] Using keystore: /home/pubuntu/.android/debug.keystore

BUILD SUCCESSFUL
Total time: 17 seconds

無事ビルドがとおったようです。

ADP1 にインストールしてちょっと確認したところ、動作もしました。

2009/05/22

AndroidでPDFが読みたいのだけど…

AndroidでPDFファイル読む時って、皆さんどうしているのでしょう?

Android Dev Phone 1(以下ADP1と記述)でAndroid Marketを探したりネットで検索してみるとPDFを読むためのアプリ(Viewer, Reader)がいくつか見つかるのですが、私の環境では読みたいPDFファイルを読むことができません。

仕方ないので、GIMPでPDFファイルをインポートしてContinus SaveというScript-fuを使用して複数のPNGファイルに変換し、Picturesという画像ビューアで読んでいました。

ところが、やはり画像ビューアでは文章を読むのに適しているとは言えません。
読む前に必ず画像の拡大をしなければならなかったり、画像を拡大しようとしたのにタッチした場所が悪くて次のファイルに移ってしまったり…。


そこでAndroid Marketに登録されているDroid Comic Viewer(以下ACVと記述)というアプリケーションを使ってみることにしました。
Droid Comic Viewer | Robot Comics [www.robotcomics.net]

ACVは複数の画像ファイルを集めた書庫ファイルを開いて読むことができます。
書庫形式はCBZ, ZIP及びACV、画像形式はJPEG, PNG, BMP 及び GIFに対応しているようです。

私はPDFをPNGに変換し、ZIPでまとめることにしました。


GIMPでContinus Saveを使用して複数のPNGファイルにエクスポートしたものをZIPにまとめればとりあえずは読めるのですが、面倒です。

PDF -> 複数の画像ファイル -> ZIP
と変換することができるUNIX用のアプリケーションを検索してみたのですが見つかりません。

無いものは作ろうということで、Ubuntu 9.04 で動作するシェルスクリプトを勉強がてら作ってみました。
内容は全く保証できませんが、とりあえず目的は果せたようです。

自分の作ったシェルスクリプトでは次を内部で実行しています。
  • pdftoppm (XPDFに含まれるらしい)
    PDFファイルをPPMファイルに変換する

  • convert (ImageMagickに含まれる)
    PPMファイルをPNGファイルに変換する

  • zip
    ZIPファイルにまとめる


シェルスクリプト内で気になっている点は次のとおりです。
「こんなことする必要はない」とか「ここはこうすればもっと良くなる」とか色々あるんでしょうが、よく分かりません。
  • 第一引数はPDFファイル、オプションとして第二引数で作成されるPNGファイルの横幅を指定する
    変換前のPDFファイルがあまりに大きいサイズだとACVで読む時に字がつぶれてしまいます
    800くらいが良いみたい

  • mktempコマンドで一時ディレクトリを作成して作業する

  • 第一引数がPDFファイルかどうかは次の構文で拡張子から判定している
    case $ARG1 in
    *.[Pp][Dd][Ff])

    ;;
    *)

    ;;
    esac

    合っているかな?

  • 第二引数が数字かどうかは次の構文で判定している
    if echo "$2" | grep -E '^[0-9]+$' >/dev/null 2>&1; then


解決できていない問題は次のとおりです。
  • pdftoppm実行時に次のようなエラーが出るPDFファイルがある
    Error: Illegal entry in bfchar block in ToUnicode CMap
    スクウェア・エニックスのアニュアルレポートで発生しましたが、特に問題なくACVで読むことはできるみたいです

  • pdftoppm、convertやzipの実行結果が失敗していることは考慮していない

  • 英語はテキトー


以下はコードです。
段々と直していきます。
#!/bin/sh
MKTEMP=$(which mktemp)
PDFTOPPM=$(which pdftoppm)
CONVERT=$(which convert)
ZIP=$(which zip)

EXECDIR=$PWD
WIDTH_VALUE=''

# check argument
echo '*** checking argument... ***'
if [ $1 ] ; then
ARG1=$1
if [ -f $ARG1 ] ; then
# $ARG1 is a file
case $ARG1 in
*.[Pp][Dd][Ff])
# $ARG1 is a PDF file
echo 'SUCCESS: '$ARG1' is a PDF file'
ZIPFILE=$EXECDIR'/'${ARG1%.[Pp][Dd][Ff]}.zip
BASENAME=${ARG1%%.*}
if [ -f $ZIPFILE ] ; then
echo 'ERROR: '$ZIPFILE' is already exist'
exit
else
if [ $2 ] ; then
if echo "$2" | grep -E '^[0-9]+$' >/dev/null 2>&1; then
WIDTH_VALUE=' -resize '$2' '
else
echo 'ERROR: '$2' is not a number'
exit
fi
fi
fi
;;
*)
echo 'ERROR: '$ARG1' is not a PDF file'
exit
;;
esac
else
# $1 is not a file
echo 'ERROR: '$ARG1' is not a file'
exit
fi
else
# $1 is not
echo 'usage: '$0' PDF-file [Image-width]'
exit
fi

echo
echo '*** checking program... ***'

if [ -x $PDFTOPPM ] ; then
echo 'SUCCESS: find '$PDFTOPPM
else
# cannot find pdftoppm
echo 'ERROR: cannot find pdftoppm'
exit
fi

if [ -x ${CONVERT} ] ; then
echo 'SUCCESS: find '$CONVERT
else
# cannot find convert
echo 'ERROR: cannot find convert'
exit
fi

if [ -x ${ZIP} ] ; then
echo 'SUCCESS: find '$ZIP
else
echo 'cannot find zip'
exit
fi

if [ -x ${MKTEMP} ] ; then
echo 'SUCCESS: find '$MKTEMP
else
echo 'ERROR: cannot find mktemp'
exit
fi

# create temporary directory
echo
echo '*** create temporary directory... ***'
TMPDIR1=$(mktemp -d)
if [ -d $TMPDIR1 ] ; then
echo 'SUCCESS: mktemp -> '$TMPDIR1

TMPDIR2=$(mktemp -d)
if [ -d $TMPDIR2 ] ; then
echo 'SUCCESS: mktemp -> '$TMPDIR2
else
echo 'ERROR: mktemp distination directory error'
fi
else
echo 'ERROR: mktemp error'
fi

echo
echo '*** converting pdf to ppm... ***'
$PDFTOPPM $ARG1 $TMPDIR1'/'$BASENAME

# cd temporary directory
cd $TMPDIR1

echo
echo '*** converting ppm to png... ***'
for i in *.ppm ; do
echo $i' to '$TMPDIR2'/'${i%.ppm}'.png'
$CONVERT $WIDTH_VALUE $i $TMPDIR2'/'${i%.ppm}.png
done

# archive
echo
echo '*** archiving... ***'
cd $TMPDIR2
$ZIP $ZIPFILE *

echo
echo '*** cleaning '$TMPDIR1'... *** '
rm -rf $TMPDIR1
echo '*** cleaning '$TMPDIR2'... *** '
rm -rf $TMPDIR2

exit


ADP1でPDFファイルを読みたいだけなんだけどなぁ…。
何でこんなことやってるのだろう?

2009/05/21

Android アプリをCUIで開発してみる(Hello, MapView のつづき)

Android アプリをCUIで開発してみる(Hello, MapView) [hanagurotanuki.blogspot.com]のつづきです。

低レベルなことやってます。

チュートリアルのHello, MapView で引き続き試してみました。
Hello, MapView | Android Developers [developer.android.com]

Androidアプリの勉強というより、Javaの初歩の初歩つまずいてるって感じです。

引き続き以下の環境で試してみます。
  • SDKはAndroid 1.5 SDK, Release 1のLinux版

  • GNOME Terminal + VIM + Ant


参照したMap APIのリファレンスです。
com.google.android.maps [code.google.com]
これがなかなか見つけられなくて非常に苦労しました。
インストールしたSDKにも含まれています。


Android アプリをCUIで開発してみる(Hello, MapView) [hanagurotanuki.blogspot.com]で行なったことにつづけて、チュートリアルにある以下の追加を行ないます。
So, we now have full interaction controls. All well and good, but what we really want our map for is custom markers and layovers. Let's add some Overlay objects to our map. To do this, we're going to implement the ItemizedOverlay class, which can manage a whole set of Overlay items for us.


Javaアプリなんて作ったことない私は、クラスの追加ってとこでちょっと考え込みました。
当然ファイルを分けたいのですが、Javaでどうやってファイル分けするんだろう…とか。

C++だったらヘッダファイルをincludeだよなーとか考えたり。

そこで、以前買ったのに全然読まずにダンボール箱にしまっておいたJavaのプログラミング本を出してきました。


2001年6月1日第1版第6刷発行


…随分昔に買ったんだなぁ。


Javaのバージョンも上がっているけど、まあ参考になるだろうとちょろちょろ読みながら行いました。

なんとかビルドが通ってAndroid Dev Phone 1(ADP1)で動作させることができました。

以下は自分がVIMでMap APIのリファレンス読みながらカリカリ書いたソースです。
これの動作を確認した後、試しにEclipseでチュートリアル通りに進めて作成したソースを見たら大体同じになっていたので、ちょっと安心しました。

・HelloMapView.java (VIMで記述)
package  com.example.hellomapview;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.ZoomControls;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import java.util.List;

public class HelloMapView extends MapActivity
{
LinearLayout linearLayout;
MapView mapView;
ZoomControls mZoom;
List mapOverlays;
Drawable drawable;
HelloItemizedOverlay itemizedOverlay;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

linearLayout = (LinearLayout) findViewById(R.id.zoomview);
mapView = (MapView) findViewById(R.id.mapview);
mZoom = (ZoomControls) mapView.getZoomControls();

linearLayout.addView(mZoom);

mapOverlays = mapView.getOverlays();
drawable =
this.getResources().getDrawable(R.drawable.androidmarker);
itemizedOverlay =
new HelloItemizedOverlay(drawable);

GeoPoint point =
new GeoPoint(19240000, -99120000);
OverlayItem overlayitem =
new OverlayItem(point, "", "");

GeoPoint point2 =
new GeoPoint(35410000, 139460000);
OverlayItem overlayitem2 =
new OverlayItem(point2, "", "");


itemizedOverlay.addOverlay(overlayitem);
itemizedOverlay.addOverlay(overlayitem2);
mapOverlays.add(itemizedOverlay);
}

@Override
protected boolean isRouteDisplayed() {
return false;
}
}


・HelloItemizedOverlay.java (VIMで記述)
package  com.example.hellomapview;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

import java.util.ArrayList;

public class HelloItemizedOverlay extends ItemizedOverlay
{
private ArrayList mOverlays =
new ArrayList();

HelloItemizedOverlay(android.graphics.drawable.Drawable defaultMarker)
{
super(boundCenterBottom(defaultMarker));
}

public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}

@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}

@Override
public int size()
{
return mOverlays.size();
}
}


size()については、チュートリアルに
We're also required to override the size() method. Replace the existing contents of the method with a size request to our ArrayList:
     return mOverlays.size();

としか書いていなくてどんな宣言にすればちょっと考えたのですが、Map APIのリファレンスのItemizedOverlayクラスのトコを見たら、
abstract  int  size()
The number of items in this overlay.

とあったので、コレに合わせました。

また、試しにEclipseでチュートリアル通りに進めてできたHelloItemizedOverlay.java見ると、
import android.graphics.drawable.Drawable;

とインポートしているのに対して、私がVIMで作成した際はMap APIリファレンスのItemizedOverlayの項目にあるコンストラクタの宣言をコピーしたため、
HelloItemizedOverlay(android.graphics.drawable.Drawable defaultMarker)
{
super(boundCenterBottom(defaultMarker));
}

としてしまいました。

いいのかな?

2009/05/19

Android アプリをCUIで開発してみる(Hello, MapView)

Portable Ubuntu for Windows(以下Portable Ubuntuと記述)を使ってCUIでのAndroid アプリ開発のお勉強です。

こちらはチュートリアルのHello, MapView で試した際のメモです。
Hello, MapView | Android Developers [developer.android.com]

相変わらずよく分からずにやっていますので、マネしないでください。


使用しているSDKはAndroid 1.5 SDK, Release 1のLinux版です。
また、GNOME Terminal + VIM + Ant を使用しました。

基本的にチュートリアル通りなのですが、気になった箇所をメモしておきます。


○ Map API の取得
チュートリアルに使うだけなので、デバッグ用のキーを取得しました。
Obtaining a Maps API Key - Google Projects for Android [code.google.com]

まずデバッグ用のkeystoreからMD5 fingerprintを取得します。
Portable Ubuntu なのでkeytstoreは
~/.android/debug.keystore
にあります。

その他の環境は以下の場所にそれぞれあるようです。
  • Windows Vista: C:\Users\<user>\.android\debug.keystore

  • Windows XP: C:\Documents and Settings\<user>\.android\debug.keystore

  • OS X and Linux: ~/.android/debug.keystore


それではPortable Ubuntu で MD5 fingerprintを取得します。
$ keytool -list -alias androiddebugkey \
> -keystore ~/.android/debug.keystore \
> -storepass android -keypass android
androiddebugkey, 2009/05/16, PrivateKeyEntry,
証明書のフィンガープリント (MD5): MD5 fingerprint


取得したMD5 fingerprintを次のURLの入力フォームに入力してMap API Keyを取得します。
Sign Up for the Android Maps API [code.google.com]
スペースが入ったりするとダメみたいです。


○ プロジェクトの作成 ~ ソースの編集
プロジェクトの雛形を作成します
後で記述しますが、--target で指定する target id は 3 じゃないとダメみたいです。
$ android create project \
--target 3 \
--package com.example.hellomapview \
--activity HelloMapView \
--path HelloMapView


ソースの編集はチュートリアル通りなのですが、HelloMapView.java で次の4つをインポートしました。
import android.widget.LinearLayout;
import android.widget.ZoomControls;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

EclipseだとCtrl + Shift + O で自動でインポートしてくれるんでしたよね。


○ プロジェクトのビルド
チュートリアルから以下のサイトリンクされています。
Google APIs Add-On - Google Projects for Android [code.google.com]

ここに次のような記述がありました。
The Google APIs add-on includes:
  • The Maps external library for Android 1.5 (API Level 3)


android create projectやandroid update projectのオプション--targetで指定するtarget idの意味をandroid list targetsで調べると次のようにあります。
$ android list targets
Available Android targets:
id: 1
Name: Android 1.1
Type: Platform
API level: 2
Skins: HVGA (default), HVGA-L, QVGA-L, QVGA-P, HVGA-P
id: 2
Name: Android 1.5
Type: Platform
API level: 3
Skins: HVGA (default), HVGA-L, QVGA-L, QVGA-P, HVGA-P
id: 3
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Description: Android + Google APIs
Based on Android 1.5 (API level 3)
Libraries:


ちょっと試しに target id の指定を変えて android update project コマンドでプロジェクトをアップデートしてビルドしてみました。

結論としては、target id は 3じゃないとダメみたいです。

試しにtarget id に 2 を指定してビルドしてみます。
$ rm -rf bin
$ android update project --target 2 --name HelloMapView --path $PWD
Updated default.properties
Updated local.properties
Updated file /home/pubuntu/D/xxx/workspace/HelloMapView/build.xml
$ ant debug
Buildfile: build.xml
[setup] Project Target: Android 1.5
[setup] API level: 3

dirs:
[echo] Creating output directories if needed...
[mkdir] Created dir: /mnt/D/xxx/workspace/HelloMapView/bin
[mkdir] Created dir: /mnt/D/xxx/workspace/HelloMapView/bin/classes

resource-src:
[echo] Generating R.java / Manifest.java from the resources...

aidl:
[echo] Compiling aidl files into Java classes...

compile:
[javac] Compiling 2 source files to /mnt/D/xxx/workspace/HelloMapView/bin/classes
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:7: パッケージ com.google.android.maps は存在しません。
[javac] import com.google.android.maps.MapActivity;
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:8: パッケージ com.google.android.maps は存在しません。
[javac] import com.google.android.maps.MapView;
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:10: シンボルを見つけられません。
[javac] シンボル: クラス MapActivity
[javac] public class HelloMapView extends MapActivity
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:13: シンボルを見つけられません。
[javac] シンボル: クラス MapView
[javac] 場所 : com.example.hellomapview.HelloMapView の クラス
[javac] MapView mapView;
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:20: シンボルを見つけられません。
[javac] シンボル: 変数 super
[javac] 場所 : com.example.hellomapview.HelloMapView の クラス
[javac] super.onCreate(savedInstanceState);
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:21: シンボルを見つけられません。
[javac] シンボル: メソッド setContentView(int)
[javac] 場所 : com.example.hellomapview.HelloMapView の クラス
[javac] setContentView(R.layout.main);
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:23: シンボルを見つけられません。
[javac] シンボル: メソッド findViewById(int)
[javac] 場所 : com.example.hellomapview.HelloMapView の クラス
[javac] linearLayout = (LinearLayout) findViewById(R.id.zoomview);
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:24: シンボルを見つけられません。
[javac] シンボル: クラス MapView
[javac] 場所 : com.example.hellomapview.HelloMapView の クラス
[javac] mapView = (MapView) findViewById(R.id.mapview);
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:24: シンボルを見つけられません。
[javac] シンボル: メソッド findViewById(int)
[javac] 場所 : com.example.hellomapview.HelloMapView の クラス
[javac] mapView = (MapView) findViewById(R.id.mapview);
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:17: メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
[javac] @Override
[javac] ^
[javac] /mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java:30: メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
[javac] @Override
[javac] ^
[javac] エラー 11 個

BUILD FAILED
/home/pubuntu/bin/android-sdk/platforms/android-1.5/templates/android_rules.xml:116: Compile failed; see the compiler error output for details.

Total time: 6 seconds

ビルドできませんでした。


今度は target id に 3 を指定してみます。
$ rm -rf bin
$ android update project --target 3 --name HelloMapView --path $PWD
Updated default.properties
Updated local.properties
Updated file /home/pubuntu/D/xxx/workspace/HelloMapView/build.xml
pubuntu@pubuntu:~/D/xxx/workspace/HelloMapView$ ant debug
Buildfile: build.xml
[setup] Project Target: Google APIs
[setup] Vendor: Google Inc.
[setup] Platform Version: 1.5
[setup] API level: 3

dirs:
[echo] Creating output directories if needed...
[mkdir] Created dir: /mnt/D/xxx/workspace/HelloMapView/bin
[mkdir] Created dir: /mnt/D/xxx/workspace/HelloMapView/bin/classes

resource-src:
[echo] Generating R.java / Manifest.java from the resources...

aidl:
[echo] Compiling aidl files into Java classes...

compile:
[javac] Compiling 2 source files to /mnt/D/xxx/workspace/HelloMapView/bin/classes
[javac] 注:/mnt/D/xxx/workspace/HelloMapView/src/com/example/hellomapview/HelloMapView.java は推奨されない API を使用またはオーバーライドしています。
[javac] 注:詳細については、-Xlint:deprecation オプションを指定して再コンパイル してください。

dex:
[echo] Converting compiled files and external libraries into bin/classes.dex...

package-resources:
[echo] Packaging resources
[aaptexec] Creating full resource package...

debug:
[apkbuilder] Creating HelloMapView-debug.apk and signing it with a debug key...
[apkbuilder] Using keystore: /home/pubuntu/.android/debug.keystore

BUILD SUCCESSFUL
Total time: 11 seconds

警告らしきものは出ますが、ビルドはできました。

2007/07/29

文字コード調査(テキトー)

Debian GNU/Linuxの文字コードがUTF-8のようですので、勉強のためにうちのシステムの文字コードについて調べてみました。

よく分からずにテキトーにやってます。

以下の記述は私のテキトーな調査を基に記述しています。
けっして信じないでください。


日本語名のフォルダを作成してみます。
以下のフォルダ作成は、Vine Linux 4.1のGNOMEターミナルエディタからDebian GNU/Linux 4.0にtelnet接続して行いました。
$ mkdir UTFです      <-- GNOMEターミナルをUTF8に設定し、
フォルダ"UTFです"を作成

$ mkdir EUC鐃叔わ申 <-- GNOMEターミナルをEUC-JPに設定し、
フォルダ"EUCです"を作成
(入力中に文字化けします)

$ ls <-- GNOMEターミナルをEUC-JPに設定
(日本語名のフォルダは全て文字化けしてしまいます)
??能?? Comic_etc EUC?任? Game HONDA KOUSHIEN TV_Cinema
UTF�с™ WallPaper WallPaper2 Web

$ ls <-- GNOMEターミナルをUTF8に設定
(UTF-8の日本語名のフォルダだけ正常に表示されます)
??ǽ?? Comic_etc EUC?Ǥ? Game HONDA KOUSHIEN TV_Cinema
UTFです WallPaper WallPaper2 Web

ここまででフォルダなどを作成したところをVine Linux 4.1のKonquerorで参照したのが下記です。
Vine Linux 4.1の文字コードはEUC-JPです。

日本語のフォルダ名がついているのは下記の3つです。
芸能人・・・Debian GNU/Linux (UTF-8の環境)に変更する以前から作成してあったフォルダ名EUC-JPのフォルダ

UTFです・・・上でGNOMEターミナルをUTF-8に設定した後に作成したフォルダ(化けてます)

EUCです・・・上でGNOMEターミナルをEUC-JPに設定した後に作成したフォルダ

GNOMEターミナルをUTF-8にして入力したフォルダ名はUTF-8で、GNOMEターミナルをEUC-JPにして入力したフォルダ名はEUC-JPで保存されていると思われます。


自分で作ったファイル名/フォルダ名の文字コードを調べるスクリプト(信頼性0)で調べると次のようになりました。
��ǽ�� (Directory)->
EUC-JP <-- 狙い通り!
Comic_etc (Directory)->
ASCII
EUC�Ǥ� (Directory)->
EUC-JP <-- 狙い通り!
Game (Directory)->
ASCII
HONDA (Directory)->
ASCII
KOUSHIEN (Directory)->
ASCII
TV_Cinema (Directory)->
ASCII
UTFです (Directory)->
UTF-8 <-- 狙い通り!
WallPaper (Directory)->
ASCII
WallPaper2 (Directory)->
ASCII
Web (Directory)->
ASCII


一応私の意図通りになっているようです。
(フォルダ名のエンコードもスクリプトの動作も)
繰り返しますが、信頼性0です。

ちなみにスクリプトの中身はこうです。
信頼性0です。
私はシェルスクリプトなんて作ったことろくにありません。
よく分かりません。
(というか、誰か教えて・・・)

中でnkfを--guessオプションをつけて使用しています。
おそらくnkf 2.0.4以降が必要だと思います。
#!/bin/sh

error_flag=1 # Initial valuable (ERROR)

for name in *; do
if [ -L "$name" ];then
# Symbolic link
type="Symbolic link"
error_flag=1
elif [ -d "$name" ]; then
# directory
type="Directory"
error_flag=0 # success
elif [ -f "$name" ]; then
# file
type="File"
error_flag=0 # success
else
# unknown
type="Unknown type"
error_flag=1 # error
fi

if [ $error_flag = 0 ]; then
echo "$name ($type)->"
echo -n " "
echo -n "$name" | nkf -guess
else
echo "$name ($type)"
fi
done

exit 0

2007/07/21

Zaurusクロス開発環境を作ってみた

ちょっと思うところあってVine Linux 4.1にZaurus用のクロス開発環境を整えることにしました。

Zaurus用のクロス開発環境は、随分前にPlamo LinuxやWindowsXPのCygwinで整えた記憶があります。
ほとんど使いませんでしたが。


(1) Zaurus開発用ツールの取得
ザウルスサポートシュテーションから一通りいただいてきてインストールしました。

うちのVine Linux 4.1では、問題なくインストールできました。


(2) 環境変数の設定
とりあえず以下の環境変数を設定。
export CROSSCOMPILE=/opt/Embedix/tools
export QPEDIR=/opt/Qtopia
export QTDIR=/opt/Qtopia
export PATH=$QTDIR/bin:$QPEDIR/bin:$PATH:/opt/Embedix/tools/bin
export TMAKEPATH=/opt/Qtopia/tmake/lib/qws/linux-x86-g++/
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH



(3) zlib-1.2.3.tar.gz をインストール
konqueror embeddedでも作ってみようかと思っていろいろやっている過程でzlibを作成しました。
こちらは開発環境(Vine Linux 4.1)の/opt/Embedix/tools/arm-linux/以下にいれました。

ちなみにkonqueror embeddedはあきらめました・・・。
ZaurusのQtopiaが古すぎて、多分ダメだろうと。

QtopiaとかQt/Embeddedが何なのかよくわかっていません。
あとでこのあたり読んで勉強してみようかな。


(4) nkf-2.0.8.tar.gz のZaurus用バイナリを作成してみる。
Makefile一番先頭の"CC = cc"を"CC = arm-linux-gcc"に変えました。
あとはmakeするだけでした。

$ file nkf
nkf: ELF 32-bit LSB executable, ARM, version 1,
for GNU/Linux 2.0.0, dynamically linked (uses shared libs),
not stripped



とりあえず出来たかなと。

2007/07/17

KDEプログラミング その5

KDEプログラミング その4」の続きです。

あいかわらずよくわからずにやっています。
どんな方法が正しいのか分かりません。


それではチュートリアルを再開します。
今回は「P3」を行いました。

とりあえずチュートリアルにあるmain.cpp, p3.h, p3.cppを作成します。
$ ls
main.cpp p3.cpp p3.h



KDEプログラミング その2」と同様の手順でmakeを行ってみます。
$ qmake -project
$ echo INCLUDEPATH += /usr/include/kde >> p3.pro
$ echo LIBS += -lkdeui -L/usr/lib/kde3 >> p3.pro
$ qmake
$ make
g++ -c -pipe -Wall -W -I/usr/include/freetype2 -O2
-m32 -march=i386 -mcpu=i686 -DQT_NO_DEBUG
-I/usr/lib/qt3/mkspecs/default -I. -I. -I/usr/include/kde
-I/usr/lib/qt3/include -o main.o main.cpp

 〜略〜

g++ -o p3 main.o p3.o moc_p3.o -L/usr/lib/qt3/lib
-L/usr/X11R6/lib -lkdeui -L/usr/lib/kde3 -lqt-mt
-lXext -lX11 -lm
p3.o(.text+0xad4): In function `MainWindow::fileOpen()':
: undefined reference to
`KFileDialog::getOpenURL(QString const&,
QString const&, QWidget*, QString const&)'
p3.o(.text+0xd64): In function `MainWindow::fileSave()':
: undefined reference to
`KFileDialog::getSaveURL(QString const&,
QString const&, QWidget*, QString const&)'
collect2: ld はステータス 1 で終了しました
make: *** [p3] エラー 1


エラーになってしまいました・・・。
今まで一度もすんなりといったことがありません。


エラーの内容を見てみると、リンク中にgetOpenURL()とgetSaveURL()が見つからないと言っている気がします。

チュートリアル
では次のような記述があります。
Note that you're encouraged to allow the user to open any URL not just local files. For this, we have used a getOpenURL dialog, which lets the user select any url. Check below for an example on how to use the KIO library.


またKFileDialog::getOpenURLの関数リファレンスはこちらにあります。

KIO Libraryに含まれるのは確かのようなので、多分リンク時に"-lkio"とか入れるのでは無いかと想像しました。
探してみると/usr/lib/libkio.soというのがありましたので、当たりかなと。


そこで最初からmakeの手順をやり直してみます。
$ make clean
rm -f moc_p3.o
rm -f moc_p3.cpp
rm -f main.o p3.o
rm -f *~ core *.core
$ ls
Makefile main.cpp p3.cpp p3.h p3.pro
$ rm Makefile p3.pro
$ ls
main.cpp p3.cpp p3.h


プロジェクトファイルから作りなおします。
$ qmake -project
$ echo INCLUDEPATH += /usr/include/kde >> p3.pro


リンクするライブラリに"-lkio"を追加します。
"-lkui"ももちろん入れておきます。
$ echo LIBS += -lkdeui -lkio -L/usr/lib/kde3 >> p3.pro


一応p3.proの確認です。
$ tail -n3 p3.pro
SOURCES += main.cpp p3.cpp
INCLUDEPATH += /usr/include/kde
LIBS += -lkdeui -lkio -L/usr/lib/kde3


一気にmakeまで行います。
$ qmake
$ make
g++ -c -pipe -Wall -W -I/usr/include/freetype2 -O2
-m32 -march=i386 -mcpu=i686 -DQT_NO_DEBUG
-I/usr/lib/qt3/mkspecs/default -I. -I.
-I/usr/include/kde -I/usr/lib/qt3/include
-o main.o main.cpp
main.cpp: function 内の `int main(int, char**)':
main.cpp:6: 警告: `__comp_ctor' is deprecated
(declared at /usr/include/kde/kapplication.h:205)
g++ -c -pipe -Wall -W -I/usr/include/freetype2 -O2
-m32 -march=i386 -mcpu=i686 -DQT_NO_DEBUG
-I/usr/lib/qt3/mkspecs/default -I. -I.
-I/usr/include/kde -I/usr/lib/qt3/include
-o p3.o p3.cpp
/usr/lib/qt3/bin/moc p3.h -o moc_p3.cpp
g++ -c -pipe -Wall -W -I/usr/include/freetype2 -O2
-m32 -march=i386 -mcpu=i686 -DQT_NO_DEBUG
-I/usr/lib/qt3/mkspecs/default -I. -I.
-I/usr/include/kde -I/usr/lib/qt3/include
-o moc_p3.o moc_p3.cpp
g++ -o p3 main.o p3.o moc_p3.o -L/usr/lib/qt3/lib
-L/usr/X11R6/lib -lkdeui -lkio -L/usr/lib/kde3
-lqt-mt -lXext -lX11 -lm
$ ls
Makefile main.cpp main.o moc_p3.cpp moc_p3.o p3*
p3.cpp p3.h p3.o p3.pro


make成功し、実行ファイルp3が作成されました。
早速実行してみます。
$ ./p3

動きました。


ソースの中身をまだ詳細を理解していないため、次はp3のソースをもっと調べることにします。
KIO Libraryを含めて。

英語だけど。

2007/07/13

KDEプログラミング その4

KDEプログラミング その3」の続きです。

引きつづき前々回のmake中に実行されたgcc(g++)コマンドのオプションを調べます。

(2) g++ -o p2 main.o -L/usr/lib/qt3/lib -L/usr/X11R6/lib -lkdeui -L/usr/lib/kde3 -lqt-mt -lXext -lX11 -lm

-o:
(1)でも出てきましたが、出力先を指定します。
今回の出力先はp2ということになります。

実行ファイルを作る場合、-oオプションを省略するとa.outというファイルが作成されるようです。


-L:
-Ldirという形式でdirを-lオプションにより検索されるディレクトリのリストに追加します。


-l:
フォントによっては分かりづらいですがL(エル)の小文字です。

マニュアルから抜粋します。
名前が library であるライブラリをリンク時に使用します。

リ ン カは、標準のライブラリ用ディレクトリのリスト中から、実際のファイル名が`liblibrary.a' であるファイルを検索します。リンカはこのファイルを、ファイル名で直接指定した場合と同様に使用します。

検 索するディレクトリには、いくつかの標準システムディレクトリと、`-L' によって指定したディレクトリが含まれます。


このあたりは以下のサイトでも読んで、もう少し勉強したいと思います。
  オブジェクト不指向の共用オブジェクト(developerWorks)


とりあえず、以上です。


KDEプログラミング その5」に続く。

KDEプログラミング その3

KDEプログラミング その2」の続きです。

チュートリアルはちょっと休憩して、gcc(g++)で使用していたコンパイルオプション位は調べてみます。

数年前に一通り調べたような記憶はあるのですが、すっかり忘れました。


前回make中に実行されたgcc(g++)コマンドは2つでした。

まず一つめです。
(1) g++ -c -pipe -Wall -W -I/usr/include/freetype2 -O2 -m32 -march=i386 -mcpu=i686 -DQT_NO_DEBUG -I/usr/lib/qt3/mkspecs/default -I. -I. -I/usr/include/kde -I/usr/lib/qt3/include -o main.o main.cpp

-c:
これはmanページを参照すると次にようにありました。
ソースファイルを、コンパイルまたはアセンブルまではしますが、リンクはしません。コンパイラの出力は、それぞれのソースファイルに対応したオブジェクトファイルとなります。

要するにmain.cppからmain.oを作っているようです。


-pipe:
manページからです。
コンパイル時のステージの間のデータの受け渡しに、テンポラリファイルではなくパイプを使用します。いくつかのシステムではアセンブラがパイプからの入力を受け付けることができないために、このオプションを指定すると失敗します。GNU アセンブラでは問題なく使用できます。

このオプションを使うメリットってなんなのでしょうか?
テンポラリファイルを使わないということなので、無駄な記憶領域を使わないとかかな?
そんなこともないか。

と疑問に思ったのでGoogleで調べてみると、記述のあるサイトがありました。
コンパイルにかかる時間が短縮されるが、より多量のメモリが必要。

アセンブラがパイプからの入力をサポートしていないシステムもあるということですが、前回も書いたとおりMakefileはqmakeを使用して作成していますので、もしかしたらqmakeがそのあたりを調べて-pipeオプションを付けるかどうか判断しているのかもしれません。


-Wall:
-W:
-Wallは覚えているのですが、-Wは何でしょう?
マニュアルの-Wallの項目には次のようにあります。
全ての上に挙げた `-W' オプションを結合したものです。これらのオプションは全て、たとえマクロとの組み合わせであっても、避けたほうがいいと我々が推奨する用法や、簡単に避けることができると我々が信じている用法に関するものです。

ちなみに、-Wは-Wallより先に記述されています。
ということは「-Wオプションはいらないんじゃないの?」と思い、調べたところ次のサイトで詳しく説明されていました。
  gcc の警告オプション -Wall と -W

上記サイトによると、-Wは-Wallには含まれないようです。
-W オプションは、-Wall では無視されたけどチェックした方がよい場合がある項目に対して警告を出すらしいです。


-I:
フォントによっては分かりづらいですが、i(アイ)の大文字です。
これは覚えています。
マニュアルには次のようにあります。
インクルードファイルの検索するディレクトリのリスト中に追加します。

これは必ず覚えておかなければいけないですよね。


-O2:
最適化オプションです。
-O・-O1→-O2→-O3と最適化の度合が増すようです。
マニュアルの-O2の項目には、次のようにあります。
さらに最適化を行います。サポートされている最適化手段のうち、空間と速度 のトレードオフを含まないものはほとんどの全て使用されます。例えばループのアンローリングや関数のインライン化は行われません。 -O と比較して、このオプションはコンパイル時間と生成コードの性能の双方を増加させます。


私の記憶では最適化に-O2を使用していることが多いようです。
ネットで調べたところ明確な記述は見つからなかったのですが、最適化を強くすると値が不正確になる場合があると書いてあるサイトがありました。


-m32:
-mはターゲットマシン固有のオプションのようです。
次のサイトに記述がありました。
  最新x86CPUで堪能する極上32&64ビット・ライフ Part1(1)

32ビットアプリケーションとしてビルドする場合は-m32、64ビットアプリケーションとしてビルドする場合は-m64を指定するようです。


-march=i386:
-mcpu=i686:
次のサイトに記述がありました。
  GCC: CPU に関する最適化オプション

-marchは指定した CPU だけで動作するようなコードをし、-mcpu より速いコードを生成することが出来き、-mcpuは-marchと違って同系列の CPU でも動作するようなコードを生成するらしいです。

"-march=i386 -mcpu=i686"と指定すると、
・i686向けのコードを吐き出すけど、i386でも動く。
・i386系で速く動くコードを吐き出す。
ということでしょうか?
分かるような分からないような。


-DQT_NO_DEBUG:
-Dオプションは-Dmacroという形式でmacroに文字列"1"を与えているようです。

QT_NO_DEBUGはどう見てもQtのマクロなので、ソース中で使用しているのでしょう。
QT_NO_DEBUGはデバッグコードを無効にしているようです。


-o:
出力先を指定します。
今回の出力先はmain.oということになります。



あー疲れた。
続きはまた今度。

KDEプログラミング その3」へ続く。

KDEプログラミング その2

KDEプログラミング その1」のつづきです。

チュートリアルを続けます。
今回は行ったのは次のページです。
  p2 : A simple KDE "Hello World" application (Yahoo!翻訳)

前回はQt3のみを使用していましたが、今回はKDEのライブラリを少し使うようです。


前回同様にサンプルプログラムをそのまま打ち込みコンパイル・・・しようと思ってもコンパイル方法が書いていないのは予想通りです。
その程度で慌てません。

そこでまた探してみました。


(1) KDE本家のサイトからなんとか探す
このあたりを読んでみたのですが、よく分かりません。
英語ですし。

なんか、難しそうなことが色々書いてあります。
こんなに難しそうなことをしなくても、サンプルプログラムのコンパイルぐらい出来るだろうと考え、KDE本家のサイトから探すのは保留しました。


(2) 日本KDEユーザ会からなんとか探す
KDE-Tutorial "KDEによるGUI作成"というのがあったのでちょっと読んでみたのですが、コンパイル方法らしきものが見つかりませんでした。
ちゃんと読めば見つかるのかもしれません。

サンプルプログラムがあったので、それのMakefileを(たとえば-lqtを-lqt-mtに)修正してやろうとしたのですが、上手く行きません。
これがなんで上手く行かないのかは検証していないのですが、あとで確認したいと思います。


(3) なにか参考になりそうなソースを探す

KDE本家のダウンロードサイトにkdiffdate-1.0.tar.gzというのがありました。

ファイルサイズも10KBと小さいですし、参考になりそうです。

ダウンロードしてきて解凍し、中のINSTALLファイルを参考にコンパイルしてみました。
$ ./conifugre
$ make

ところが、makeでエラーになります。

./configure で作成したMakefileを見ると、次のところの値がとれていませんでした。
 -I$(KDEDIR)/include
 -L$(KDEDIR)/lib

Makefile中でKDEDIRを設定している箇所はありませんし、環境変数も設定されていません。
しょうがないので次のように修正しました。
 -I$(KDEDIR)/include → -I/usr/include/kde
 -L$(KDEDIR)/lib → -L/usr/lib/kde3

再度makeしました。
$ make

今度は成功したみたいです。


中に入っているconfigureファイルを確認したところ、このソフトkdiffdate.pro から Makefile を作成しているようです。

.proのファイルは前回はqmake -projectコマンドで作成しました。

kdiffdate.proを見てみると、KDE関連の追加と思われる次の箇所がありました。
 INCLUDEPATH += $(KDEDIR)/include
 LIBS += -lkdeui -L$(KDEDIR)/lib

さっき$(KDEDIR)とかあったのは、どうやらkdiffdate.proに書いてあったからのようです。多分。


(4) いよいよチュートリアルのプログラム(p2)をコンパイルする

なんとなくやることが見えてきましたので、再チャレンジです。

上記のとおり、色々試行錯誤してやっています。
正しいのか分かりません。
マネしないでください。


(a) p2.proの作成
$ ls
main.cpp
$ qmake -project
$ ls
main.cpp p2.pro


(b) p2.proの修正
$ cat p2.pro

 〜(略)〜

TEMPLATE = app
CONFIG -= moc
INCLUDEPATH += .

# Input
SOURCES += main.cpp


最後に次の2行を追加します。
 INCLUDEPATH += $(KDEDIR)/include
 LIBS += -lkdeui -L$(KDEDIR)/lib

$ echo INCLUDEPATH += /usr/include/kde >> p2.pro
$ echo LIBS += -lkdeui -L/usr/lib/kde3 >> p2.pro
$ tail -n3 p2.pro
SOURCES += main.cpp
INCLUDEPATH += /usr/include/kde
LIBS += -lkdeui -L/usr/lib/kde3


(c) Makefileの作成
$ ls
main.cpp p2.pro
$ qmake
$ ls
Makefile main.cpp p2.pro


(d) make
$ make
g++ -c -pipe -Wall -W -I/usr/include/freetype2 -O2
-m32 -march=i386 -mcpu=i686 -DQT_NO_DEBUG
-I/usr/lib/qt3/mkspecs/default -I. -I.
-I/usr/include/kde -I/usr/lib/qt3/include -o main.o main.cpp
main.cpp: function 内の `int main(int, char**)':
main.cpp:7: 警告: `__comp_ctor' is deprecated (declared at
/usr/include/kde/kapplication.h:205)
g++ -o p2 main.o -L/usr/lib/qt3/lib
-L/usr/X11R6/lib -lkdeui -L/usr/lib/kde3
-lqt-mt -lXext -lX11 -lm
$


警告は出ますが、なんとか出来たみたいです。


それでは実行してみます。
$ ./p2



おおっ。
前回のQtプログラムと若干違うみたいです。
ちなみに前回はこんな感じでした。



これがKDEの底力か!

・・・警告が気になりますけど。


しかし、サンプルプログラムでこんなにてこずるとは。

ちゃんと読めば、「(1) KDE本家のサイトからなんとか探す」で分かった気がします。


KDEプログラミング その3」へ続く。

KDEプログラミング その1

最近Vine Linux 4.1でKDEを使いはじめました。

で、リハビリがてらKDEのプログラミングでもしてみようかと思い付き、KDEの本家のページのチュートリアルでもやってみることにしました。
  Development/Tutorials/KDE3 (Yahoo!翻訳)

ちなみに、うちのVine Linux 4.1に入っているKDEは3.5.7、Qtは3.3.5みたいです。


まずはこちらの「Hello World!」のmain.cppをそのまま写してコンパイル・・・、しようとしたけどコンパイル方法が書いていない。

日本KDEユーザ会のチュートリアルのこちらのページの一番下にあるのに倣い、次のようにコマンドを叩きました。

$ g++ -I$QTDIR/include -o hello main.cpp
-L$QTDIR/lib -lqt
/usr/bin/ld: cannot find -lqt
collect2: ld はステータス 1 で終了しました


・・・エラーになります。

-lqtが見付からないということなので、探してみました。

$ ls $QTDIR/lib
libdesignercore.a libqt-mt.so@ libqt-mt.so.3.3.5*
libqui.so.1.0@ libeditor.a libqt-mt.so.3@
libqui.so@ libqui.so.1.0.0* libqassistantclient.a
libqt-mt.so.3.3@ libqui.so.1@


確かにlibqt.soとかはありません。

libqt-mt.soというのがなんとなく当たりかなと想像し、これで試してみました。

(ちなみに次に打ったコマンドは試行錯誤中のものです。これが正解ではないと思います。)

$ g++ -I$QTDIR/include -o hello main.cpp
-L$QTDIR/lib -lqt-mt

$ ls
hello* main.cpp


成功したみたいです。
実行してみたところ、次のようなプログラムが動きました。



ただ、「-lqt-mt」で正しいのか分かりません。
Qt3でのコンパイル方法をGoogleで調べてみたのですが、よく分かりませんでした。


Trolltechのサイトもチュートリアルがありました。
  Qt Reference Documentation (Yahoo!翻訳)

こちらを見てみるとg++を直接叩くのではなく、qmakeを使用してMakefileを作成しています。
それに倣ってやってみました。

$ rm hello ←最初に作ったプログラムを削除
$ qmake -project
$ ls
main.cpp p1.pro
$ qmake
$ ls
Makefile main.cpp p1.pro


Makefileが出来たみたいです。

それではmakeしてみます。

$ make
g++ -c -pipe -Wall -W -I/usr/include/freetype2 -O2
-m32 -march=i386 -mcpu=i686 -DQT_NO_DEBUG
-I/usr/lib/qt3/mkspecs/default -I. -I.
-I/usr/lib/qt3/include -o main.o main.cpp
g++ -o p1 main.o -L/usr/lib/qt3/lib
-L/usr/X11R6/lib -lqt-mt -lXext -lX11 -lm
$ ls
Makefile main.cpp main.o p1* p1.pro


p1というプログラムができました。

p1という名前になったのは、カレントディレクトリがp1だからだと思います。多分。

で、実行してみました。


動きました。
最初のとまったく同じですけど。


こんな感じで、少しずつ覚えてみようかと思います。


最近できたGoogleブック検索でタイトルQtで調べると、他の国ではQt3とかQt4の本が出てきますね。

アマゾンで調べると「Qt GUIプログラミング」という本が見つかりました。

レビューを読むとQt3みたいです。

私もとりあえずKDE3とQt3を使ってみようと思っているので参考に買ってみようかな。


KDEプログラミング その2」につづく