BREW/C++
BREWでC++プログラミングを自由に行うためには、色々と解決しなければならない問題があるのは、みなさんご存じだとは思いますが、NDAが厳しいので、表だった情報交換も出来ないのが困ったところ。ならば自前でがんばりましょーと、情報を集めてなんとかプログラミングができるようになったものの、一段落すると、新たな問題が。それを解決してまた一段落すると、また新たな…と無限ループを形成してます。どうしたものだか。
自分なりに調べて、解決した結果をまとめてみました。「もっとイイ方法があるじゃまいか」と思う人は、教えてください。
■基本的な問題(ARMCC/GCC共通)
- static/global変数を利用可能にする
これは、リンク時に問題として顕在化しますが、Qualcommのelf2modで解決。
- 浮動小数点演算をネイティブに利用可能にする
これは、コンパイラオプションで、コンパイラの生成するヘルパ関数を調整するのと、ヘルパを自前で用意すれば解決。
■C++に特有な問題
- staicオブジェクト(ARMCC)
シングルトンパターンなどを実装する際に、staticオブジェクトを利用しますが、staticオブジェクトを実装すると、コンパイラが、アプリケーション終了時にstaticオブジェクトのデストラクタを呼び出す機構を実装するために、__cxa_atexit()への参照を生成します。
この__cxa_atexit()は、標準ライブラリ内に実装されているため、標準ライブラリを使用できないBREWでは、困ったことになります。
この関数のプロトタイプは、
int __cxa_atexit(void (*func)(void*), void* arg, void* dso);
このようになっており、この関数の中では、渡された関数へのポインタを管理し、管理した関数リストを、アプリケーションの終了時に呼び出さなければなりません。
ただし、ARMCCのマニュアルによれば、「一般的な」アプリケーション実行環境(OS)では、アプリケーションの終了時に、未開放メモリ領域を自動的に開放するので、エントリポイントのみ実装すれば問題ないと書いてあったので、
int __cxa_atexit(void (*func)(void*), void* arg, void* dso) { return 0; }
として、実装。確かデストラクタは呼ばれていたと思ったが、どうだったかな?
BREWって、leaked memory の自動開放機構って、実装されてるのかしらん?
- staicオブジェクト(GCC)
コンパイルオプションに -fno-use-cxa-atexit を指定することで、解決するらすぃ。