Anzeige

Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京

hecomi
31. May 2013
Anzeige

Más contenido relacionado

Similar a Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京(20)

Anzeige

Último(20)

Anzeige

Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京

  1. ++ + C++ とJavaScript で広がる世界 @hecomi Boost.勉強会 #11 東京
  2. Introduction •  C++ と JavaScript が関連するお話について、  広く浅く簡単に世界観を紹介したいと思います
  3. Introduction •  対象者 –  C++, JavaScript 知ってる人・興味がある人 •  内容 –  C++ と JS が関連した技術群それぞれについて、  Hello world に毛が生えたくらいの内容を紹介します –  ちなみに Boost 成分 1 ㍉ もありません…
  4. 自己紹介 •  Name : @hecomi •  Blog : http://d.hatena.ne.jp/hecomi/
  5. 自己紹介 – 未来っぽいお部屋 Node.js 上で動作する自作 C++ モジュールと組み合わせて作った未来っぽいお部屋
  6. 目次 •  C++ + JS の世界感 •  V8 •  Node.js •  Qt Quick •  Native Client •  Emscripten
  7. C++ + JS の世界感 BrowserBrowser JavaScript と言えばブラウザ…
  8. C++ + JS の世界感 BrowserBrowser JavaScript エンジン C++ で書かれている!
  9. C++ + JS の世界感 BrowserBrowser JavaScript エンジン ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) ブラウザ以外でも…
  10. C++ + JS の世界感 BrowserBrowser JavaScript エンジン ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) サーバサイド JavaScript 他にも有名ドコロで…
  11. C++ + JS の世界感 BrowserBrowser JavaScript エンジン ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) サーバサイド JavaScript アプリケーション開発 フレームワーク 他にも有名ドコロで…
  12. C++ + JS の世界感 BrowserBrowser JavaScript エンジン ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) サーバサイド JavaScript アプリケーション開発 フレームワーク NativeClient ネイティブアプリを ブラウザ上で動かす ブラウザの話に戻ると…
  13. C++ + JS の世界感 BrowserBrowser JavaScript エンジン ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) サーバサイド JavaScript アプリケーション開発 フレームワーク NativeClient ネイティブアプリを ブラウザ上で動かす Emscripten C++ を JS に変換 ブラウザの話に戻ると…
  14. C++ + JS の世界感 BrowserBrowser JavaScript エンジン mobile JavaScript Java C++ JNI ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) サーバサイド JavaScript アプリケーション開発 フレームワーク NativeClient ネイティブアプリを ブラウザ上で動かす Emscripten C++ を JS に変換 モバイル周りは更に色々ありますが省略 ex.) Android
  15. C++ + JS の世界感 BrowserBrowser JavaScript エンジン ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) サーバサイド JavaScript アプリケーション開発 フレームワーク NativeClient ネイティブアプリを ブラウザ上で動かす Emscripten C++ を JS に変換 mobile JavaScript Java C++ JNI ex.) Android
  16. C++ + JS の世界感 BrowserBrowser JavaScript エンジン ゲーム用途 例: SimCity (WebKit + v8 で UI を記述) サーバサイド JavaScript アプリケーション開発 フレームワーク NativeClient ネイティブアプリを ブラウザ上で動かす Emscripten C++ を JS に変換 mobile JavaScript Java C++ JNI ex.) Android
  17. V8 Chrome でおなじみの JavaScript エンジン
  18. 内容 •  Introduction •  V8 を使った JS の実行 •  C++ の関数 à JavaScript の関数 •  C++ のクラス à JavaScript のクラス
  19. Introduction •  V8 は、Chrome にも搭載されている C++ で書か れた JavaScript エンジン その他のオープンなエンジンには SpiderMonkey (C), Rhino (Java), JavaScriptCore (C++) 等があります
  20. Introduction - インストール                        h#ps://github.com/v8/v8 or                    %  brew  install  v8                      %  sudo  ap;tude  install  libv8-­‐dev
  21. 動かしてみる
  22. V8 を使った JS の実行 ※ 最近は Context.Dispose で Isolate を引数に指定しない場合は Warning が出るようになったようです
  23. Sample Code この辺りは何となく 分かるけど…
  24. V8 を使った JS の実行 Context??
  25. •  独立した JS をある V8 インスタンスの中で実行する環境 •  JS は built-in 変数/関数も書換可能なのでグローバル空間を分離 •  2 つ目以降の Context の生成はローコストで可能 •  iframe とかイメージすると分かりやすいです Context Context A Built-in func / obj Custom func / obj Context B Built-in func / obj Custom func / obj
  26. V8 を使った JS の実行 Handle??
  27. Handle •  ヒープ内の JS オブジェクトの位置の参照 –  GC する度に JS オブジェクトの実体のヒープ位置は変わってしまうので –  JS の世界の変数とのやり取りはこの Handle を通じて行う •  Local Handle と Persistent Handle の 2 種類がある –  Local の寿命は Handle Scope で決定 –  Persistent は明示的に Dispose するまで破棄されない Heap “hogehoge” 100 Function Handle Scope Local<String> Local<Number> Persistent<Function>
  28. V8 を使った JS の実行 Persistent ハンドルを返す Local ハンドルを返す
  29. 関数を追加したい!
  30. こんな風にやります
  31. こんな風にやります この戻り値、引数で関数を つくります
  32. こんな風にやります Value は JS の基本型(Number, Array, Object…) の基底クラスで、IsNumber() 等で型を確かめ、ToNumber() 等でアッ プキャスト出来ます。 Arguments は各引数(Value 型)に [ ] 演算子でアクセスでき、This や Callee などを参照できます。
  33. こんな風にやります Context 生成時に global オブジェクト を指定することができます。
  34. こんな風にやります print という関数を JS で呼ぶと、 ↑の print が実行されるように global オブジェクトにセットします
  35. こんな風にやります $ clang++ print_test.cpp –o print_test $ ./print_test 100 + 200 = 300 実行 :
  36. lambda 版
  37. クラスを追加したい!
  38. クラスの追加 概要 myClass の internal field に void* で保存 が呼ばれ、 C++ 側であらかじめ登録しておいた関数内で、 プロパティの読み書きやメソッド呼び出しのタイミングで、 事前に登録しておいた C++ の関数が呼ばれる。その内部では、 void* から my_class* へキャストして、メンバ変数 hoge の 読み書きや、メンバ関数 piyo() の呼び出しをする。
  39. 例えばこんなクラスを…
  40. 例えばこんなクラスを… メンバ変数 setter / getter
  41. 例えばこんなクラスを… なんか凄いことするメンバ関数
  42. こんな風にします
  43. こんな風にします クラス内部の static 関数経由でのみ 呼ばれるようになるので private 化 setter / getter を JS 側から 呼ばれる形に変換
  44. こんな風にします JS の世界へ送り出す処理を記述 JS 側で new された時と GC された時の処理 piyo を JS 側から 呼べるようにする
  45. JS の世界とつなぐ処理 my_class::ctor を元にした関数を作成
  46. JS の世界とつなぐ処理 JS のインスタンス変数、プロトタイプ変数 に相当する変数を取得
  47. JS の世界とつなぐ処理 そこへプロパティや そのアクセサをセットしたり メソッドをセット したりします
  48. JS の世界とつなぐ処理 この関数をグローバル空間に追加します
  49. JS の世界とつなぐ処理 さっきは飛ばしましたが、ここでは 内部に JS からは見えない フィールドを 1 個作成しています new 時に呼ばれるコンストラクタを見てみます
  50. JS の世界とつなぐ処理 こんな風 this オブジェクトに インスタンスを埋め込みます ( 0 はインデックス )
  51. JS の世界とつなぐ処理 参照されなくなったら削除する処理を書きます
  52. JS の世界とつなぐ処理 getter / setter では内部に保存した インスタンスを取り出して使います
  53. JS の世界とつなぐ処理 getter / setter では内部に保存した インスタンスを取り出して使います
  54. JS の世界とつなぐ処理 メソッドでも同じです
  55. JS の世界とつなぐ処理 $ ./hello hoge hoge から fuga に書き換えられました fuga piyopiyo 実行 :
  56. 参考文献 •  Chrome V8 Embedder’s Guide –  https://developers.google.com/v8/embed?hl=ja
  57. NODE.JS サーバサイド JavaScript 環境
  58. 内容 •  Introduction •  Node.js の世界観 •  C++ モジュールの作成
  59. Introduction •  V8 をエンジンとして利用したサーバサイドの JavaScript プラットフォーム •  ブラウザの JavaScript では出来なそうなことが 色々簡単に出来る環境です
  60. Introduction •  ファイルを読み込んだり…
  61. Introduction •  HTTP サーバを立てたり…
  62. Introduction •  HTTP サーバを立てたり…
  63.                                              h#p://nodejs.jp/nodejs.org_ja/ Introduction - インストール                        h#ps://github.com/hokaccha/nodebrew or バージョン指定出来るのでこっちがオススメ
  64. Node.js の世界観 JS  でつくりたいもの
  65. Node.js の世界観 JS  でつくりたいもの コアモジュール fs,  h#p  などの組み込みモジュール
  66. Node.js の世界観 JS  でつくりたいもの コアモジュール npm  モジュール $  npm  install  hoge  で追加できるモジュール fs,  h#p  などの組み込みモジュール ※ Node Packaged Modules 31,184 個 (2013/05/31 時点) も 登録されている。 WebSocket を使ったり、DB とつない だり、各サービスにアクセスしたり…
  67. Node.js の世界観 JS  でつくりたいもの コアモジュール npm  モジュール 自作モジュール $  npm  install  hoge  で追加できるモジュール fs,  h#p  などの組み込みモジュール
  68. Node.js の世界観 未来っぽいお部屋 コアモジュール npm  モジュール 自作モジュール twi#er,  socket.io,  express,  serialport,  …   fs,  h#p  などの組み込みモジュール 音声認識、発話、各種ガジェット操作、… 例えば冒頭紹介した
  69. Node.js の世界観 未来っぽいお部屋 コアモジュール npm  モジュール 自作モジュール twi#er,  socket.io,  express,  serialport,  …   fs,  h#p  などの組み込みモジュール C++ と組み合わせれば 出来ることの幅が拡がる! 音声認識、発話、各種ガジェット操作、… 例えば冒頭紹介した
  70. どうやって作るの?
  71. C++ モジュールの作成
  72. C++ モジュールの作成 JS の世界へ送り出す関数 Node.js の世界へ C++ の 関数を送り出す処理
  73. C++ モジュールの作成 v8 で global に関数をセットした時と 同じ形に展開
  74. C++ モジュールの作成 hello という名前のモジュールを作成 & JS 側へ変数/関数をセットする関数を指定(init)
  75. C++ モジュールの作成 hello という名前のモジュールを作成 & JS 側へ変数/関数をセットする関数を指定(init)
  76. C++ モジュールの作成 $ npm install node-gyp -g $ node-gyp configure build binding.gyp コンパイル : 先ほどと同じモジュール名 gyp (generate your projects) 用の 設定を json 形式で記述 ビルドは node 用の gyp (node-gyp) を用いる
  77. C++ モジュールの作成 $ node hello world hello.js 実行 :
  78. C++ モジュールの作成 $ node hello world hello.js 実行 :
  79. 参考文献 •  Node.js マニュアル & ドキュメンテーション –  http://nodejs.jp/nodejs.org_ja/api/addons.html
  80. QT QUICK UI 記述言語 QML でクロスプラットフォームアプリを簡単に作成
  81. 内容 •  Introduction •  QML の例 •  C++ バインディング
  82. Introduction •  Qt –  C++ で書かれたクロスプラットフォーム対応のアプリケー ション開発フレームワーク •  実績: Skype / Google Earth / Photoshop Elements •  Qt Quick –  C++ でなく QML という JavaScriptをベースにした言語で UI 周りを記述する環境 •  Qt 4.x (Qt Quick 1) では WebKit の JavaScriptCore がエンジン だったが、Qt 5 (Qt Quick 2) からは V8 がエンジンになりました
  83. Introduction •  インストール –  開発には C++ と JS の世界をまたがってコード補完して くれる Qt Creator が便利です •  http://qt-project.org/downloads
  84. QML の例 ProgressBar.qml main.qml
  85. QML の例 ProgressBar.qml main.qml JS が使える!
  86. QML の例 ProgressBar.qml main.qml プロパティの値でも!
  87. QML の例 ProgressBar.qml main.qml プログレスバーつき WebView
  88. QML の例 ProgressBar.qml main.qml プログレスバーつき WebView 簡単!
  89. C++ バインディング •  QML だけでは込み入ったことは出来ない –  例えばローカルファイル IO とか •  そこで C++ バインディング!
  90. C++ バインディング •  色々な方法がある –  QML の要素を C++ で使う –  QML の関数を C++ から呼ぶ –  C++ のクラスを QML から使う –  C++ で QML で使える型を定義する
  91. C++ バインディング •  色々な方法がある –  QML の要素を C++ で使う –  QML の関数を C++ から呼ぶ –  C++ のクラスを QML から使う –  C++ で QML で使える型を定義する その他の方法については以下を参照!: http://d.hatena.ne.jp/hecomi/20130503/1367594609 JS に関係する所
  92. QML の関数を C++ から呼ぶ C++ QML
  93. QML の関数を C++ から呼ぶ arr と obj を受け取り output に出力する関数 C++ QML
  94. QML の関数を C++ から呼ぶ QMLを表示 C++ QML
  95. QML の関数を C++ から呼ぶ 配列と オブジェクト を作成 C++ QML
  96. QML の関数を C++ から呼ぶ setText を呼ぶ! C++ QML
  97. QML の関数を C++ から呼ぶ setText を呼ぶ! C++ QML
  98. QML の関数を C++ から呼ぶ setText を呼ぶ! 簡単! C++ QML
  99. C++ のクラスを QML から使う myclass.h main.qml main.cpp
  100. C++ のクラスを QML から使う myclass.h main.qml main.cpp my という名前で MyClass をセット
  101. C++ のクラスを QML から使う myclass.h main.qml main.cpp my という名前で MyClass をセット そのまま使える!
  102. C++ のクラスを QML から使う myclass.h main.qml main.cpp 超簡単!
  103. C++ のクラスを QML から使う myclass.h main.qml main.cpp 超簡単! このオマジナイは何?
  104. moc •  Qt には Meta Object Compiler (moc) という ツールがある •  qmake すると C++ から C++ を吐き出す –  Q_INVOKABLE や signal / slot などのキーワードをア ノーテーションとして解釈してコードを生成 •  キーワードは C++ に影響を与えないよう define されている –  Q_OBJECT はそこに必要な幾つかのメンバを展開する •  例えば qt_static_metacall という静的なメンバ関数を展開、こ の中で Q_INVOKABLE のついたメンバ関数を呼ぶ
  105. 自動生成されたコード例 moc_myclass.cpp myclass.h 内の Q_OBJECT で qt_static_metacall の宣言が生成され、 定義は別途生成された moc_myclass.cpp にて行われる。 ここで呼ばれる
  106. 参考文献 •  Using QML Bindings in C++ Applications –  http://harmattan-dev.nokia.com/docs/platform-api- reference/xml/daily-docs/libqt4/qtbinding.html •  QtQuick での C++ × QML バインディングについ てまとめてみた –  http://d.hatena.ne.jp/hecomi/20130503/1367594609
  107. NATIVE CLIENT ブラウザ上でネイティブアプリを動かす
  108. 内容 •  Introduction •  Hello World を動かしてみる
  109. Introduction •  Native Client (NaCl: 塩) はブラウザ上で安全にネ イティブコードを実行 –  サンプル: https://developers.google.com/showcase/ •  JS とやり取りも出来る! Chrome extension としても利用可能 (↑ SSH Client が動く Secure Shell)
  110. Install •  参照 –  Native Client の導入と Hello World までのまとめ •  http://d.hatena.ne.jp/hecomi/20130128/1359372772
  111. Native Client の世界観 ① HTML nmf C++ nexe make アーキの振り分け embed タグを起点としてロード
  112. Native Client の世界観 ② NaClPepper APIJavaScript ローカルファイル IO 2D/3D グラフィックス (OpenGL ES 2.0) オーディオ マウス/キーボード/ ゲームパッド 等々… Pepper Plugin API (PPAPI) を経由して ブラウザを超えた機能にアクセスする
  113. Native Client の世界観 ② NaClPepper API NaCl (塩) に対し Pepper (胡椒) JavaScript ローカルファイル IO 2D/3D グラフィックス (OpenGL ES 2.0) オーディオ マウス/キーボード/ ゲームパッド 等々… Pepper Plugin API (PPAPI) を経由して ブラウザを超えた機能にアクセスする
  114. Native Client の世界観 ③ JavaScript C++ PostMessage() postMessage() HandleMessage ‘message’ Event Listener
  115. Hello World を動かしてみる
  116. Hello World を動かしてみる まず embed タグ生成時に pp::CreateModule が呼ばれる pp::Module* を返すので継承したクラスを作成
  117. Hello World を動かしてみる pp::Module::CreateInstance が呼ばれる
  118. Hello World を動かしてみる pp::Instance* を返すので 継承したクラスを作成する
  119. Hello World を動かしてみる
  120. Hello World を動かしてみる JavaScript からのメッセージを受け取る
  121. Hello World を動かしてみる 渡されたメッセージの処理
  122. Hello World を動かしてみる JS からのメッセージを受け取ったので 今度は JS 側へメッセージを送ってみる
  123. Hello World を動かしてみる
  124. Hello World を動かしてみる 読み込まれたら hello を C++ 側へ送る (HandleMessage が呼ばれる)
  125. Hello World を動かしてみる C++ 側からのメッセージを受け取る (HandleMessage 内の PostMessage)
  126. Hello World を動かしてみる C++ 側からのメッセージを受け取る (HandleMessage 内の PostMessage)
  127. 参考文献 •  Native Client の導入と Hello World までのまとめ –  http://d.hatena.ne.jp/hecomi/20130128/1359372772 •  Native Client — Google Developers –  https://developers.google.com/native-client/
  128. EMSCRIPTEN C++ のコードを JavaScript へ変換
  129. 内容 •  Introduction •  変換して動かしてみる
  130. Introduction •  LLVM-IR を JavaScript に変換! –  LLVM … Clang のバックエンドにもなっているコンパイ ラ基盤 –  LLVM-IR … LLVM の中間表現 LLVM のロゴかこいい
  131. Introduction C++ LLVM-IR JavaScript Clang Emscripten
  132. Introduction •  色々なものが変換されています –  https://github.com/kripken/emscripten/wiki
  133. Introduction •  色々なものが変換されています –  https://github.com/kripken/emscripten/wiki mruby
  134. Introduction •  色々なものが変換されています –  https://github.com/kripken/emscripten/wiki mruby gnuplot
  135. Introduction •  色々なものが変換されています –  https://github.com/kripken/emscripten/wiki mruby gnuplot unreal engine
  136. Introduction •  色々なものが変換されています –  https://github.com/kripken/emscripten/wiki mruby gnuplot unreal engine Qt
  137. インストール •  参照 –  Emscripten で C++ の Hello World を JavaScript に 変換してみた •  http://d.hatena.ne.jp/hecomi/20130416/1366124901
  138. Hello world を変換してみる hello.cpp
  139. Hello world を変換してみる $ em++ hello.cpp –o hello.js $ node hello.js Hello, world! hello.cpp
  140. Hello world を変換してみる $ em++ hello.cpp –o hello.js $ node hello.js Hello, world! $ em++ hello.cpp –o hello.html $ open hello.html hello.cpp
  141. Hello world を変換してみる $ em++ hello.cpp –o hello.js $ node hello.js Hello, world! $ em++ hello.cpp –o hello.html $ open hello.html hello.cpp
  142. Hello world を変換してみる $ em++ hello.cpp –o hello.js $ node hello.js Hello, world! $ em++ hello.cpp –o hello.html $ open hello.html hello.cpp ( ^ω^) cpp ここに cpp があるじゃろ?
  143. Hello world を変換してみる $ em++ hello.cpp –o hello.js $ node hello.js Hello, world! $ em++ hello.cpp –o hello.html $ open hello.html hello.cpp ( ^ω^) これを em++ すると…
  144. Hello world を変換してみる $ em++ hello.cpp –o hello.js $ node hello.js Hello, world! $ em++ hello.cpp –o hello.html $ open hello.html main 関数 hello.cpp hello.js ( ^ω^) こうじゃ
  145. Hello world を変換してみる $ em++ hello.cpp –o hello.js $ node hello.js Hello, world! $ em++ hello.cpp –o hello.html $ open hello.html main 関数 123536  行! hello.jshello.cpp ( ^ω^) こうじゃ
  146. 速度どうなの? •  普通に JS 書くよりは数倍程度遅い…、が、
  147. 速度どうなの? •  Emscripten は asm.js 形式の js を吐き出す –  asm.js は JavaScript を拡張せずに型付をして高速化を はかる JavaScript のサブセット –  ex. (x + y) | 0 // int32 •  asm.js 実装した JS エンジン OdinMonkey を積む Firefox (nightly) でデモ動かすとヌルヌル –  http://www.unrealengine.com/html5/
  148. 速度どうなの?
  149. 参考文献 •  “実戦 Emscripten –  http://www.mozilla.jp/static/docs/events/vision/2012/06- ushiroad.pdf •  asm.js spec –  http://asmjs.org/spec/latest/ •  BIG WEB APP? COMPILE IT! –  http://kripken.github.io/mloc_emscripten_talk/
  150. まとめ •  C++ と JavaScript が関連する世界を幾つか紹介 –  V8 –  Node.js –  Qt Quick –  NaCl –  Emscripten •  コレ以外にも色々あると思いますのでご存知でしたら 教えて下さい m(_ _)m
  151. ++ + C++ とJavaScript で広がる世界 @hecomi Boost.勉強会 #11 東京
Anzeige