約 3,962,271 件
https://w.atwiki.jp/torinikudaisuki/pages/12.html
1:このプログラムがやっていること 2:送信プロセス 3:伝搬プロセス 4:受信プロセス Uan-cw-exampleの実行ログ
https://w.atwiki.jp/tmiya/pages/69.html
11.3 高度な例 離散イベントシミュレーション(Extended Example Discrete Event Simulation) 代入と高階関数がどのように興味深い形で結びつくか、例をとおして考えます。ここでは、デジタル回路シミュレータを構築します。 この例は Abelson と Sussman の本[ASS96]から借りました。彼らの基本的な (Scheme の) コードを、継承でコードを再利用できるオブジェクト指向によって拡張しています。この例は、一般的な離散イベントのシミュレーションプログラムが、どのように構造化され構築されるかも示します。 デジタル回路を記述する小さな言語から始めます。デジタル回路は 結線 と function box から構築されます。結線は信号を運び、function box は信号を変換します。信号は ture と false の真偽値で表現します。 次は基本的な function box です。 インバーター 信号を反転します。 AND ゲート 入力の論理積を出力に設定します。 OR ゲート 入力の論理和を出力に設定します。 ほかの function box は、これらの組み合わせで作れます。 ゲートには 遅延 があり、ゲートの出力変化は、入力からいくらか時間が経ってから起きます。 デジタル回路用言語 デジタル回路の要素を、次の Scala クラスと関数によって記述します。まず、結線を表す Wire クラスです。結線は次のようにして生成できます。 val a = new Wire val b = new Wire val c = new Wire 次に、手続きです。 def inverter(input Wire, output Wire) def andGate(a1 Wire, a2 Wire, output Wire) def orGate(o1 Wire, o2 Wire, output Wire) これらの手続きは、われわれが必要とする基本ゲートを (副作用として)「作成」します。これらを使ってもっと複雑な function box を作れます。たとえば半加算器は、次のように定義できます。 def halfAdder(a Wire, b Wire, s Wire, c Wire) { val d = new Wire val e = new Wire orGate(a, b, d) andGate(a, b, c) inverter(c, e) andGate(d, e, s) } この抽象化は、それ自体で使用できます。たとえば、全加算器の定義で def fullAdder(a Wire, b Wire, cin Wire, sum Wire, cout Wire) { val s = new Wire val c1 = new Wire val c2 = new Wire halfAdder(a, cin, s, c1) halfAdder(b, s, sum, c2) orGate(c1, c2, cout) } このようにして、クラス Wire および関数 inverter、andGate、orGate は、ユーザーがデジタル回路を定義できる小さな言語を表現しています。では、回路をシミュレートできるように、このクラスと関数群に実装を与えましょう。実装は、離散イベントシミュレーション用のシンプルで一般的な API に基づきます。 シミュレーション API 離散イベントシミュレーションは、ユーザーが定義した アクション を指定された 時刻 に実行します。 アクション は、パラメータをとらず Unit を返す関数として表されます。 type Action = () = Unit 時刻 はシミュレーション上のものであり、「壁時計」が指す現実の時刻ではありません。 具体的なシミュレーションは、抽象クラス Simulation を継承したオブジェクトの内部で行われます。このクラスは次のシグネチャを持ちます。 abstract class Simulation { def currentTime Int def afterDelay(delay Int, action = Action) def run() } currentTime は、現在のシミュレーション上の時刻を整数値として返します。afterDelay は、currentTime から指定された時間が経過したときにアクションが実行されるよう、スケジュールします。run は、実行するアクションがなくなるまでシミュレーションを実行します。 結線クラス 結線は3つの基本的なアクションをサポートする必要があります。 ・getSignal 結線の現在の信号を返します。 ・setSignal(sig Boolean) 結線の信号を sig に更新します。 ・addAction(p Action) 指定された手続き p を結線の アクション に付加します。結線の信号が変更されるたびに、付加されたすべてのアクション手続きを実行します。 Wire クラスの実装例を示します。 class Wire { private var sigVal = false private var actions List[Action] = List() def getSignal = sigVal def setSignal(s Boolean) = if (s != sigVal) { sigVal = s actions.foreach(action = action()) } def addAction(a Action) { actions = a actions; a() } } 2つのプライベート変数が結線の状態を作り上げます。変数 sigVal は結線の現在の信号を表し、変数 actions は現在結線に付加されているアクション手続きを表します。 インバータクラス インバータ(Not 回路)を、入力の結線にアクションをインストールすることで実装します。アクションは入力信号を反転して出力信号とします。アクションが効果を現すのは、入力が変化してからシミュレーション時間 InverterDelay 経過後でなくてはなりません。以上より、次の実装が導かれます。 def inverter(input Wire, output Wire) { def invertAction() { val inputSig = input.getSignal afterDelay(InverterDelay) { output setSignal !inputSig } } input addAction invertAction } AND ゲートクラス AND ゲートは、インバーターの類推で実装できます。andGate のアクションは、入力信号の論理積を出力することです。それは、2つの入力のいずれかが変化してから、シミュレーション時間 AndGateDelay 経過後におきる必要があります。実装は次のようになります。 def andGate(a1 Wire, a2 Wire, output Wire) { def andAction() { val a1Sig = a1.getSignal val a2Sig = a2.getSignal afterDelay(AndGateDelay) { output setSignal (a1Sig a2Sig) } } a1 addAction andAction a2 addAction andAction } 演習 11.3.1 OR ゲートの実装を書きなさい 演習 11.3.2 OR ゲートの別の定義方法として、インバーターと AND ゲートを組み合わせる方法があります。関数 orGate を、andGate とinverter を使って定義しなさい。また、この関数の遅延(delay)時間は? シミュレーションクラス さあ、あとは Simulation クラスを実装すれば出来あがりです。考え方としては、我々が Simulation オブジェクト内部の面倒を見て、 agenda (予定表)のアクションを実行するようにしてやります。agenda はアクションと、実行すべき時刻のペアのリストとして表現されます。agenda リストは実行すべき時刻でソートしておいて、早いアクションが先にくるようにします。 abstract class Simulation { case class WorkItem(time Int, action Action) private type Agenda = List[WorkItem] private var agenda Agenda = List() また、プライベート変数 curtime によって、シミュレーション上の時刻を追跡します。 private var curtime = 0 メソッド afterDelay(delay, block) を適用すると、要素 WorkItem(currentTime + delay, () = block) は agenda リストの適切な場所に挿入されます。 private def insert(ag Agenda, item WorkItem) Agenda = if (ag.isEmpty || item.time ag.head.time) item ag else ag.head insert(ag.tail, item) def afterDelay(delay Int)(block = Unit) { val item = WorkItem(currentTime + delay, () = block) agenda = insert(agenda, item) } メソッド run を適用すると、agenda から要素を取り除いてそのアクションを実行する、ということが繰り返されます。それは agenda が空になるまで続きます。 private def next() { agenda match { case WorkItem(time, action) rest = agenda = rest; curtime = time; action() case List() = } } def run() { afterDelay(0) { println("*** simulation started ***") } while (!agenda.isEmpty) next() } シミュレータの実行 シミュレータを走らせる前に、結線上の信号変化を追跡する方法を用意します。そのための関数 probe を書きます。 def probe(name String, wire Wire) { wire addAction { println(name + " " + currentTime + " new_value = " + wire.getSignal) } } さあ、シミュレータを動かします。まず、4つの結線を定義し、そのうちの二つに probe をセットしましょう。 scala val input1, input2, sum, carry = new Wire scala probe("sum", sum) sum 0 new_value = false scala probe("carry", carry) carry 0 new_value = false 半加算器の回路を定義してみましょう。 scala halfAdder(input1, input2, sum, carry) 最後に、2つの入力結線の信号を順番に true に設定して、シミュレータを走らせましょう。 scala input1 setSignal true; run *** simulation started *** sum 8 new_value = true scala input2 setSignal true; run carry 11 new_value = true sum 15 new_value = false 前ページ 11 章 目次 次ページ 名前 コメント
https://w.atwiki.jp/techsure/pages/36.html
このページはhttp //www.vgleaks.com/durango-memory-system-example/からの引用です Durango Memory System Example This whole system example demonstrates what the memory bandwidth might look like when thewhole systemis working under a typical load (this numbers are only predictions not measured numbers) This example assumes what’s expected to be a typical CPU load and a maximum GPU load Three display planes are enabled at 1080p resolution. Display write-back is writing a 1080p image at 60 FPS. Moveenginesare idle. Read bandwidth of the command buffer and index buffer is 4 GB/s. Regular GPU rendering consumes the rest of the available bandwidth. This diagram shows our prediction of the typical bandwidth for the north bridge clients and the typical available bandwidth for the GPU clients (which are shown in blue). Let’s start by describing the CPU. Although each CPU module can request up to 20.8 GB/s of bandwidth for read and for write, the typical bandwidth you should expect for the CPU is 4 GB/s per CPU module per direction—about 16 GB/s altogether. You can expect typical bandwidth to be around 3 GB/s per direction for the audio, HDD, Camera, and USBs. The Kinect Sensor is the main consumer of the bandwidth. For example, peak bandwidth to and from the HDD is only about 50 MB/s, so the HDD cannot be seen as a major bandwidth consumer. Because the GPU is usually pushed to the maximum, you can expect typical coherent bandwidth to be about 25 GB/s. However, this amount depends on how many resources are made snoopable. Currently, we are not able tell exactly how much of that access will be hitting the CPU’s caches and how much of the access much will go to DRAM. So as we said above, this figure is highly speculative at the moment. The estimated 25 GB/s of bandwidth for coherent memory access does not account for the non-coherent memory access of the GPU. The coherent bandwidth that can flow through the north bridge is a limited at 30 GB/s. Under typical conditions, this limit shouldn’t cause you problems. But during a high load on the coherent memory traffic, the north bridge might become saturated. Once the north bridge becomes saturated, you may notice increased latencies for memory access. CPU memory access that is Write Combined does not fall under this limitation nor does GPU memory access that is non-coherent. Finally let’s compute how much bandwidth is left for the non-coherent GPU access to consume. Let’s assume that The sum of bandwidth from the north bridge to DRAM is 25 GB/s. Some portion of the GPU coherent bandwidth misses the L2 caches. Non-coherent CPU bandwidth is 3 GB/s. This leaves 42 GB/s of DRAM bandwidth available to the GPU clients.
https://w.atwiki.jp/tmiya/pages/62.html
10.2 For 内包表記によるクエリ (Querying with For-Comprehensions) for 内包表記は、データベースのクエリ言語による一般的操作と本質的に同じです。たとえば、データベース books があり、本のリストとして表現されているとしましょう。ただし Book は次のように定義されるものとします。 case class Book(title String, authors List[String]) 次はデータベースの小さなサンプルです。 val books List[Book] = List( Book("Structure and Interpretation of Computer Programs", List("Abelson, Harold", "Sussman, Gerald J.")), Book("Principles of Compiler Design", List("Aho, Alfred", "Ullman, Jeffrey")), Book("Programming in Modula-2", List("Wirth, Niklaus")), Book("Introduction to Functional Programming"), List("Bird, Richard")), Book("The Java Language Specification", List("Gosling, James", "Joy, Bill", "Steele, Guy", "Bracha, Gilad"))) このとき、著者の姓が "Ullman" である本すべての書名を探すには、 for (b - books; a - b.authors if a startsWith "Ullman") yield b.title (ここで startsWith は java.lang.String のメソッド)。あるいは書名が "Program" で始まる本の書名を探すには for (b - books if (b.title indexOf "Program") = 0) yield b.title あるいは、少なくとも二冊の本を書いたすべての著者の名前をデータベース上で探すには、 for (b1 - books; b2 - books if b1 != b2; a1 - b1.authors; a2 - b2.authors if a1 == a2) yield a1 最後のコードはまだ完全ではありません。なぜなら著者が結果リストに複数回現れるからです。結果リストから重複した著者を除く必要があります。これは次の関数を使えばできます。 def removeDuplicates[A](xs List[A]) List[A] = if (xs.isEmpty) xs else xs.head removeDuplicates(xs.tail filter (x = x != xs.head)) メソッド removeDuplicates の最後の式は for 内包表記を使って、等価に次のように表現できます。 xs.head removeDuplicates(for (x - xs.tail if x != xs.head) yield x) 前ページ 10 章 目次 次ページ 名前 コメント
https://w.atwiki.jp/tanasai/pages/25.html
山田 太郎(tana12) 事務・装飾 ドカベン。東京スーパースターズの捕手。三冠王を獲得するほどのバットコントロール、長打力、勝負強さを兼ね備えている。また捕手としてもその強肩とインサイドワークで最高の評価をうけている。
https://w.atwiki.jp/tmiya/pages/47.html
8.1 型パラメータの境界 クラスをジェネリックにする方法を知った今では、前に書いたクラスの中には一般化した方が自然なものがあります。たとえばクラス IntSet は、任意の要素型を持てるように一般化できます。やってみましょう。ジェネリックな集合の抽象クラスは簡単に書けます。 abstract class Set[A] { def incl(x A) Set[A] def contains(x A) Boolean } しかしもし二分木として実装し続けたいなら、問題に直面します。メソッド contains と incl はどちらも、要素をメソッド と を使って比較します。IntSet については、これは OK です。なぜなら Int はそれら2つのメソッドを持っているからです。しかし任意の型パラメータ a に対しては、それは保証できません。したがって先の実装、たとえば contains ではコンパイルエラーが生じるでしょう。 def contains(x Int) Boolean = if (x elem) left contains x ^ not a member of type A. 問題を解決する一つの方法は、型 A と置き換え可能な正当な型を、正しい型のメソッド と を持つ型だけに制限することです。Scala 標準ライブラリには、型 A の値と ( と によって) 比較可能な値を表現する、トレイト Ordered[A] があります。このトレイトは次のように定義されています。 /** データを完全に順序づけるためのクラス */ trait Ordered[A] { /** this をオペランド that と比較した結果。 * returns x where * x 0 iff this that * x == 0 iff this == that * x 0 iff this that */ def compare(that A) Int def (that A) Boolean = (this compare that) 0 def (that A) Boolean = (this compare that) 0 def = (that A) Boolean = (this compare that) = 0 def = (that A) Boolean = (this compare that) = 0 def compareTo(that A) Int = compare(that) } 型が Ordered のサブタイプであることを要求することで、互換性を強制できます。これは Set の型パラメータに上界境界(upper bound)を与えることでなされます。 trait Set[A Ordered[A]] { def incl(x A) Set[A] def contains(x A) Boolean } パラメータ宣言 A Ordered[A] は型パラメータとしての A を、A は Ordered[A] のサブタイプでなくてはならない、として導入します。すなわち、その値は同じ型の値と比較可能でなくてはなりません。 この制限によって、ジェネリックな集合の抽象化を、前の IntSet の場合と同じように実装できます。 class EmptySet[A Ordered[A]] extends Set[A] { def contains(x A) Boolean = false def incl(x A) Set[A] = new NonEmptySet(x, new EmptySet[A], new EmptySet[A]) } class NonEmptySet[A Ordered[A]] (elem A, left Set[A], right Set[A]) extends Set[A] { def contains(x A) Boolean = if (x elem) left contains x else if (x elem) right contains x else true def incl(x A) Set[A] = if (x elem) new NonEmptySet(elem, left incl x, right) else if (x elem) new NonEmptySet(elem, left, right incl x) else this } オブジェクト生成 new NonEmptySet(...) において、型引数を書いていないことに注意して下さい。多相的メソッドと同様に、コンストラクタ呼び出しで型引数が書かれていない時、それは値引数と期待される結果型(戻り値型)から推論されます。 以下はジェネリックな集合の抽象化を使う例です。まづ、Ordered のサブクラスを次のように作りましょう。 case class Num(value Double) extends Ordered[Num] { def compare(that Num) Int = if (this.value that.value) -1 else if (this.value that.value) 1 else 0 } すると val s = new EmptySet[Num].incl(Num(1.0)).incl(Num(2.0)) s.contains(Num(1.5)) これは OK です。なぜなら型 Num はトレイト Ordered[Num] を実装しているからです。しかし次の例はエラーになります。 val s = new EmptySet[java.io.File] ^ java.io.File does not conform to type parameter bound Ordered[java.io.File]. 型パラメータ境界の問題は、前もって考えておくべきことです。もし Num を Ordered のサブクラスとして宣言していなければ、Num を集合の要素として使用できません。同様に、Java から継承した Int、Double、String といった型は Ordered のサブクラスではないので、それらの型の値は集合の要素として使用できません。 それらの型を要素として許すもっと柔軟なデザインがあります。 可視境界 (view bound)を今までに見てきた単純な型境界の代わりに使うことです。先の例でこれによって起こる変更は、単に型パラメータが次のようになることです。 trait Set[A % Ordered[A]] ... class EmptySet[A % Ordered[A]] ... class NonEmptySet[A % Ordered[A]] ... 可視境界 % は通常の上限境界 より弱いです。可視境界をもつ型パラメータ節 [A % T] は単に、境界づけられる型 A が境界となる型 T へ、暗黙の型変換を使って 変換可能 なことだけを指定します。 Scala ライブラリは、プリミティブ型や String を含む数多くの型について、暗黙の型変換を事前に定義しています。したがって、再デザインされた集合の抽象化は、これらの型についてもインスタンス化できます。暗黙の変換と可視境界に関する更なる説明は第 15 章にあります。 前ページ 8 章 目次 次ページ bound, type bound, view bound の良い訳語が判らない...。 -- tmiya (2008-05-19 00 34 40) 束縛、っていっちゃうとやっぱまずいですかね。「縛り」の方がまし? -- a (2009-07-25 03 51 29) 名前 コメント
https://w.atwiki.jp/tmiya/pages/39.html
5.3 例 関数の不動点探索 数 x は次の条件を満たす時に、関数 f の 不動点 と呼ばれます。 f(x) = x . いくつかの関数 f では、初期推定値から始めて、値が変化しなくなる (あるいは変化が小さな許容量以下になる) まで f を繰り返し適用することで不動点を求めることができます。それは、数列 x, f(x), f(f(x)), f(f(f(x))), ... が、f の不動点に収束すれば可能です。このアイデアを取り入れたのが次の「不動点を求める関数」です。 val tolerance = 0.0001 def isCloseEnough(x Double, y Double) = abs((x - y) / x) tolerance def fixedPoint(f Double = Double)(firstGuess Double) = { def iterate(guess Double) Double = { val next = f(guess) if (isCloseEnough(guess, next)) next else iterate(next) } iterate(firstGuess) } このアイデアを平方根を求める関数の再設計に応用します。sqrt の仕様から始めましょう。 sqrt(x) = y ただし y * y = x = y ただし y = x / y したがって sqrt(x) は関数 y= x / y の不動点です。このことは sqrt(x) は不動点の反復で計算できることを示しています。 def sqrt(x double) = fixedPoint(y = x / y)(1.0) しかし実際にやってみると、計算は収束しないことが分かります。現在の推定値を追跡する print 文付きの不動点関数を実装してみます。 def fixedPoint(f Double = Double)(firstGuess Double) = { def iterate(guess Double) Double = { val next = f(guess) println(next) if (isCloseEnough(guess, next)) next else iterate(next) } iterate(firstGuess) } すると sqrt(2) は次のようになります。 2.0 1.0 2.0 1.0 2.0 ... このような振動を抑える一つの方法は、推定値の急激な変化を防ぐことです。これは元の数列上で、続く値を 平均 すれば可能です。 scala def sqrt(x Double) = fixedPoint(y = (y + x/y) / 2)(1.0) sqrt (Double)Double scala sqrt(2.0) 1.5 1.4166666666666665 1.4142156862745097 1.4142135623746899 1.4142135623746899 実際、fixedPoint 関数を展開すると、前に 4.4 節で定義した不動点の定義と全く同じになります。 前の例では、もし関数を引数として渡すことができれば、言語の表現力が大幅に強化される、ということを示しました。次の例では、関数を返す関数もたいへん有用であることを示します。 不動点の繰り返しをもう一度考えてみましょう。√(x) が関数 y = x / y の不動点であることから始めました。次いで、続く値を平均することで繰り返しを収束させました。この 平均による減衰 というテクニックは一般的ですから、別の関数で包むことにします。 def averageDamp(f Double = Double)(x Double) = (x + f(x)) / 2 averageDump を使って、平方根関数を次のように再設計できます。 def sqrt(x Double) = fixedPoint(averageDamp(y = x/y))(1.0) Exercise 5.3.1 Write a function for cube roots using fixedPoint and averageDamp. } これはアルゴリズムの要素を可能な限り明確に表現しています。 演習 5.3.1 fixedPoint と averageDump を使って、立方根を求める関数を書きなさい。 前ページ 5 章 目次 次ページ 名前 コメント
https://w.atwiki.jp/tmiya/pages/54.html
9.1 リストの使用 (Using Lists) リスト型 配列と同じくリストは 等質 です。つまり、リストの要素はすべて同じ型です。要素型 T のリストの型は List[T] と書きます(Java の T[] は配列です)。 val fruit List[String] = List("apples", "oranges", "pears") val nums List[Int] = List(1, 2, 3, 4) val diag3 List[List[Int]] = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) val empty List[Int] = List() リストのコンストラクタ すべてのリストは2つの基本的なコンストラクタである Nil と ("cons" と発音する) から作られます。Nil は空リストを表します。中置演算子 は、リストの拡張を表します。つまり x xs は、最初の要素が x で、その後にリスト xs (の要素) が続くリストを表します。したがって、先ほどのリストの値は、次のようにも定義できます (実際、前述の定義は次の単なる糖衣構文です)。 val fruit = "apples" ("oranges" ("pears" Nil)) val nums = 1 (2 (3 (4 Nil))) val diag3 = (1 (0 (0 Nil))) (0 (1 (0 Nil))) (0 (0 (1 Nil))) Nil val empty = Nil 操作は右結合です。A B C は A (B C) と解釈されます。したがって先ほどの定義で、括弧は省略できます。たとえば次のように短く書けます。 val nums = 1 2 3 4 Nil リストの基本操作 リストのすべての操作は、次の三つを使って表現できます。 head リストの最初の要素を返す。 tail 最初の要素以外の、すべての要素からなるリストを返す。 isEmpty リストが空である時、かつその時に限り true を返す。 これらの操作は、リストオブジェクトのメソッドとして定義されています。操作対象のリストから、それらの操作を選択して呼び出してみましょう。たとえば empty.isEmpty = true fruit.isEmpty = false fruit.head = "apples" fruit.tail.head = "oranges" diag3.head = List(1, 0, 0) head と tail メソッドは非空リストに対してだけ定義されています。空リストから選択された場合は、例外を投げます。 リストを扱う例として、数のリストを昇順にソートすることを考えましょう。ソートする一つの簡単な方法は 挿入ソート であり、次のようにします。最初の要素が x で残りが xs であるような非空リストをソートするには、残りの xs をソートして、要素 x をその結果の正しい場所に挿入します。空リストのソートは空リストになります。Scala のコードで表現すると def isort(xs List[Int]) List[Int] = if (xs.isEmpty) Nil else insert(xs.head, isort(xs.tail)) 演習 9.1.1 書かれていない関数 insert を実装しなさい。 リストパターン 実際のところ、 は Scala の標準ライブラリでケースクラスとして定義されています。ですから、Nil と コンストラクタからなるパターンを用いた、パターンマッチングでリストを分解できます。たとえば isort は次のようにも書けます。 def isort(xs List[Int]) List[Int] = xs match { case List() = List() case x xs1 = insert(x, isort(xs1)) } ただし、 def insert(x Int, xs List[Int]) List[Int] = xs match { case List() = List(x) case y ys = if (x = y) x xs else y insert(x, ys) } 前ページ 9 章 目次 次ページ 名前 コメント
https://w.atwiki.jp/sampleisbest/pages/394.html
開発環境 Apache Flex SDK 4.12.1 FlashDevelop 4.6.2.5 実行環境 Microsoft Windows 8.1 (64bit) プロジェクトの種類 ActionScript 3/AS3 Project プロジェクト名 PointAtExample
https://w.atwiki.jp/bambooflow/pages/106.html
doExampleL 勉強は、まずはコンソールアプリから始めればよさそう。 CommonFramwork.hを使えば簡単みたい。 使用するときはeuser.libライブラリが必要。 .mmpファイル参照(抜粋) SYSTEMINCLUDE \epoc32\include ・・・ LIBRARY euser.lib HelloWorld.cpp #include "CommonFramework.h" // do the exampleLOCAL_C void doExampleL() { _LIT(KHelloWorldText,"Hello world!\n"); console- Printf(KHelloWorldText); } CommonFramework.h #ifndef __CommonFramework_H#define __CommonFramework_H #include e32base.h #include e32cons.h _LIT(KTxtEPOC32EX,"EXAMPLES");_LIT(KTxtExampleCode,"Symbian OS Example Code");_LIT(KFormatFailed,"failed leave code=%d");_LIT(KTxtOK,"ok");_LIT(KTxtPressAnyKey," [press any key]"); // publicLOCAL_D CConsoleBase* console; // write all your messages to thisLOCAL_C void doExampleL(); // code this function for the real example // privateLOCAL_C void callExampleL(); // initialize with cleanup stack, then do example GLDEF_C TInt E32Main() // main function called by E32 { __UHEAP_MARK; CTrapCleanup* cleanup=CTrapCleanup New(); // get clean-up stack TRAPD(error,callExampleL()); // more initialization, then do example __ASSERT_ALWAYS(!error,User Panic(KTxtEPOC32EX,error)); delete cleanup; // destroy clean-up stack __UHEAP_MARKEND; return 0; // and return } LOCAL_C void callExampleL() // initialize and call example code under cleanup stack { console=Console NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen)); CleanupStack PushL(console); TRAPD(error,doExampleL()); // perform example function if (error) console- Printf(KFormatFailed, error); else console- Printf(KTxtOK); console- Printf(KTxtPressAnyKey); console- Getch(); // get and ignore character CleanupStack PopAndDestroy(); // close console } #endif 説明 E32Main エントリポイント。 Cでいうところのmain関数にあたる。 プログラムはここから実行が開始される。 __UHEAP_MARK __UHEAP_MARKENDマクロ __UHEAP_MARK マクロで始まるコードのセクション内で割り当てられたヒープ領域が、__UHEAP_MARKEND マクロに到達したときに、すべて削除されているかどうかをテストする。 未削除の割り当てがあると__UHEAP_MARKENDでエラーメッセージが出てパニックとなる。 マクロはネストすることも可能。 __UHEAP_CHECKALL、やコード内マーク部分では__UHEAP_CHECKで値を指定したヒープメモリのテストもできる。 デバッグビルド時のみ定義が有効。 CTrapCleanup New() クリーンナップスタックを生成する。 __ASSERT_ALWAYSマクロ __ASSERT_ALWAYS (c, p) (void)((c)||(p,0)) アサート。すべてのビルドで有効。 __ASSERT_DEBUGはデバッグ時のみ有効。 TRAPD (_r, _s)マクロ トラップハーネスの下で指定したステートメントを実行する。 _rにあるUser Leave() の結果を_rが受け取る。 トラップハーネス内で本体処理が行われている。 参考 以下を参考にして、 Base E32_EKA2