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

8,017 views
7,906 views

Published on

Boost.勉強会 #11 東京(http://partake.in/events/e75cde86-75c8-47ce-b647-2dbd0495b053)で発表した資料です。補足資料はこちら: http://d.hatena.ne.jp/hecomi/20130604/1370356501

Published in: Technology
0 Comments
26 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
8,017
On SlideShare
0
From Embeds
0
Number of Embeds
1,564
Actions
Shares
0
Downloads
69
Comments
0
Likes
26
Embeds 0
No embeds

No notes for slide

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

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

×