Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 .. _tutorial: | 1 .. _tutorial: |
| 2 | 2 |
| 3 ############################# | 3 ############################# |
| 4 C++ Tutorial: Getting Started | 4 C++ Tutorial: Getting Started |
| 5 ############################# | 5 ############################# |
| 6 | 6 |
| 7 .. contents:: | 7 .. contents:: |
| 8 :local: | 8 :local: |
| 9 :backlinks: none | 9 :backlinks: none |
| 10 :depth: 2 | 10 :depth: 2 |
| 11 | 11 |
| 12 Overview | 12 Overview |
| 13 ======== | 13 ======== |
| 14 | 14 |
| 15 This tutorial shows you how to create, compile, and run a Native Client web | 15 This tutorial shows how to build and run a web application using Portable Native |
| 16 application. The Native Client module you will create as part of the web | 16 Client (PNaCl). This is a client-side application that uses HTML, JavaScript and |
| 17 application will be written in C++. | 17 a Native Client module written in C++. The PNaCl toolchain is used to enable |
| 18 running the Native Client module directly from a web page. | |
| 18 | 19 |
| 19 We recommend reading the :doc:`Native Client Technical Overview | 20 It's recommended to read the :doc:`Native Client Technical Overview |
| 20 <../overview>` prior to going through this tutorial. | 21 <../overview>` prior to going through this tutorial. |
| 21 | 22 |
| 22 Parts in a Native Client application | |
| 23 ------------------------------------ | |
| 24 | |
| 25 A Native Client web application consists of at least three parts: | |
| 26 **TODO(binji)**: This is duplicated in the technical overview. Make sure it is | |
| 27 consistent in each. | |
| 28 | |
| 29 * A **web page** (*\*.html*) | |
| 30 | |
| 31 The web page can include HTML, JavaScript, and CSS (the JavaScript and CSS | |
| 32 can also go in separate .js and .css files). | |
| 33 | |
| 34 * A **Native Client module** (*\*.c* or *\*.cc* before compiling; *\*.nexe* | |
| 35 after compiling) | |
| 36 | |
| 37 Native Client modules can be written in C or C++. Modules use the Pepper API, | |
| 38 included in the SDK, as a bridge between the browser and the modules. | |
| 39 | |
| 40 * A **Manifest** file (*\*.nmf*) | |
| 41 | |
| 42 Browsers use an application's manifest file to determine which compiled Native | |
| 43 Client module to load based on the instruction set architecture of the user's | |
| 44 machine (e.g., x86-32, x86-64, or ARM). | |
| 45 | |
| 46 What the application in this tutorial does | 23 What the application in this tutorial does |
| 47 ------------------------------------------ | 24 ------------------------------------------ |
| 48 | 25 |
| 49 The application in this tutorial shows how to load a Native Client module in a | 26 The application in this tutorial shows how to load a Native Client module in a |
| 50 web page, and how to send messages between JavaScript code and the C or C++ | 27 web page, and how to send messages between JavaScript and the C++ code in the |
| 51 code in the Native Client module. In this simple application, the JavaScript | 28 Native Client module. In this simple application, the JavaScript code in the web |
| 52 code in the web page sends a 'hello' message to the Native Client module. When | 29 page sends a ``'hello'`` message to the Native Client module. When the Native |
| 53 the Native Client module receives a message, it checks whether the message is | 30 Client module receives a message, it checks whether the message is equal to the |
| 54 equal to the string 'hello'. If it is, the Native Client module returns a | 31 string ``'hello'``. If it is, the Native Client module returns a message saying |
| 55 message saying 'hello from NaCl'. A JavaScript alert panel displays the message | 32 ``'hello from NaCl'``. A JavaScript alert panel displays the message received |
| 56 received from the Native Client module. | 33 from the Native Client module. |
| 57 | 34 |
| 58 This tutorial also shows you how to create a set of template files that you can | 35 Communication between JavaScript and Native Client modules |
| 59 use as a starting point for a Native Client application. The template code sets | 36 ---------------------------------------------------------- |
| 60 up a simple message handler on the Native Client side, and includes boilerplate | |
| 61 code in the HTML file for adding an event listener to the web page to receive | |
| 62 messages from the Native Client module. | |
| 63 | 37 |
| 64 Communication between JavaScript code and Native Client modules | 38 The Native Client programming model supports bidirectional communication between |
| 65 --------------------------------------------------------------- | 39 JavaScript and the Native Clinet module (C/C++ code). Both sides can initiate |
|
jvoung (off chromium)
2013/09/19 21:46:35
Clinet -> Client
eliben
2013/09/19 23:19:21
Dnoe
| |
| 66 | 40 and respond to messages. In all cases, the communication is asynchronous: The |
| 67 Communication between JavaScript code in the browser and C or C++ code in a | 41 caller (JavaScript or the Native Client module) sends a message, but the caller |
| 68 Native Client module is two-way: JavaScript code can send messages to the | 42 does not wait for, or may not even expect, a response. This behavior is |
| 69 Native Client module; the C or C++ code can respond to messages from | |
| 70 JavaScript, or it can initiate its own messages to JavaScript. In all cases, | |
| 71 the communication is asynchronous: The caller (the JavaScript code in the | |
| 72 browser or the C/C++ code in the Native Client module) sends a message, but the | |
| 73 caller does not wait for, or may not even expect, a response. This behavior is | |
| 74 analogous to client/server communication on the web, where the client posts a | 43 analogous to client/server communication on the web, where the client posts a |
| 75 message to the server and returns immediately. The Native Client messaging | 44 message to the server and returns immediately. The Native Client messaging |
| 76 system is part of the Pepper API, and is described in detail in the | 45 system is part of the Pepper API, and is described in detail in |
| 77 :doc:`Messaging System <coding/message-system>` chapter in the Developer's | 46 :doc:`Developer's Guide: Messaging System <coding/message-system>`. |
| 78 Guide. | 47 |
| 48 TODO: would it be better to compare to web-worker communication? | |
|
jvoung (off chromium)
2013/09/19 21:46:35
The message-system doc does compare it to web-work
binji
2013/09/19 22:06:50
I think this is better. It is actually very simila
eliben
2013/09/19 23:19:21
I'm sorry, too much context to disambiguate "this"
binji
2013/09/20 17:14:44
Apologies, I think the way you have written it now
| |
| 79 | 49 |
| 80 Step 1: Download and install the Native Client SDK | 50 Step 1: Download and install the Native Client SDK |
| 81 ================================================== | 51 ================================================== |
| 82 | 52 |
| 83 Follow the instructions on the :doc:`Download <../sdk/download>` page to | 53 Follow the instructions on the :doc:`Download <../sdk/download>` page to |
| 84 download and install the Native Client SDK. | 54 download and install the Native Client SDK. |
| 85 | 55 |
| 86 .. Note:: | 56 .. _tutorial_step_2: |
| 87 :class: caution | |
| 88 | |
| 89 **Important:** A number of tools in the SDK require Python to run. Python is | |
| 90 typically included on Mac and Linux systems, but not on Windows systems. To | |
| 91 check whether you have Python installed on your system, enter the | |
| 92 '``python``' command on the command line; you should get the interactive | |
| 93 Python prompt (``>>>``). On Mac systems, you also need to install '``make``' | |
| 94 in order to build and run the examples in the SDK; one easy way to get | |
| 95 '``make``', along with several other useful tools, is to install Xcode | |
| 96 Developer Tools. Follow the instructions at the top of the :doc:`Download | |
| 97 <../sdk/download>` page if you need to install Python and/or Xcode | |
| 98 Developer Tools. | |
| 99 | 57 |
| 100 Step 2: Start a local server | 58 Step 2: Start a local server |
| 101 ============================ | 59 ============================ |
| 102 | 60 |
| 103 TODO(binji): This is not necessary anymore; we can use ``make run``. Some of | 61 To simulate a production environment, the SDK provides a simple web server that |
| 104 the information about why you need a webserver is still useful though... | 62 can be used to serve the application on ``localhost``. A convenience Makefile |
| 105 Remove? | 63 rule called ``serve`` is the easiest way to invoke it: |
| 106 | |
| 107 To protect against security vulnerabilities, you must load Native Client | |
| 108 modules from a web server (either remote or local). **Simply dragging and | |
| 109 dropping Native Client files into the browser address bar will not work.** For | |
| 110 more information, read about the `Same Origin Policy | |
| 111 <http://www.w3.org/Security/wiki/Same_Origin_Policy>`_, which protects the | |
| 112 user's file system from outside access. | |
| 113 | |
| 114 The Native Client SDK includes a simple Python web server that you can use to | |
| 115 run applications that you build (including the application in this tutorial). | |
| 116 The server is located in the tools directory. To start the web server, go to | |
| 117 the examples directory in the SDK bundle that you are using and run the | |
| 118 ``httpd.py`` script. For example, if you are using the ``pepper_28`` bundle, | |
| 119 run the following commands: | |
| 120 | 64 |
| 121 .. naclcode:: | 65 .. naclcode:: |
| 122 :prettyprint: 0 | 66 :prettyprint: 0 |
| 123 | 67 |
| 124 cd pepper_28/examples | 68 $ cd pepper_$(VERSION)/getting_started |
| 125 python ../tools/httpd.py | 69 $ make serve |
| 126 | 70 |
| 127 If you don't specify a port number, the server defaults to port 5103, and you | 71 .. Note:: |
| 128 can access the server at http://localhost:5103. | 72 :class: note |
| 129 | 73 |
| 130 Of course, you don't have to use the server included in the SDK---any web server | 74 The SDK may consist of several "bundles", one per Chrome/Pepper version (see |
| 131 will do. If you prefer to use another web server already installed on your | 75 :doc:`versioning information <../version>`). In the sample invocation above |
| 132 system, that's fine. Note also that there are ways to run Native Client | 76 ``pepper_$(VERSION)`` refers to the specific version you want to use. For |
| 133 applications during development without a server, but these techniques require | 77 example, ``pepper_31``. If you don't know which version you need, use the |
| 134 you to create additional files for your application (see :doc:`Running Native | 78 latest one. |
|
jvoung (off chromium)
2013/09/19 21:46:35
Latest one is canary which might churn more?
Or d
binji
2013/09/19 22:06:50
I'm not sure this is the best advice. Shouldn't we
eliben
2013/09/19 23:19:21
Yes. How do I say "latest stable" one? The one wit
binji
2013/09/20 17:14:44
No, when you run "nacl_sdk list" it will display s
| |
| 135 Client Applications <devcycle/running>` for details). For this tutorial, | |
| 136 your application must come from a server. | |
| 137 | 79 |
| 138 .. _step_3: | 80 If no port number is specified, the server defaults to port 5103, and can be |
| 81 accessed at http://localhost:5103. | |
| 139 | 82 |
| 140 Step 3: Set up Google Chrome | 83 Any server can be used for the purpose of development. The one provided with the |
| 141 ============================ | 84 SDK is just a convenience, not a requirement. |
| 142 | 85 |
| 143 Set up the Chrome browser as follows: | 86 .. _tutorial_step_3: |
| 144 | 87 |
| 145 a. Make sure you are using the minimum required version of Chrome. | 88 Step 3: Set up the Chrome browser |
| 89 ================================= | |
| 146 | 90 |
| 147 * Your version of Chrome must be equal to or greater than the version of your | 91 PNaCl is enabled by default in Chrome version 31 and later. Please make sure |
| 148 Pepper bundle. For example, if you're developing with the ``pepper_28`` | 92 that you have a suitable version to work through this tutorial. It's also |
| 149 bundle, you must use Google Chrome version 28 or greater. To find out what | 93 important to use a Chrome version that's the same or newer than the SDK bundle |
| 150 version of Chrome you're using, type ``about:chrome`` or ``about:version`` | 94 used to build the Native Client modules. |
| 151 in the Chrome address bar. | |
| 152 | 95 |
| 153 b. Enable the Native Client flag in Chrome. (Native Client is enabled by | 96 .. Note:: |
| 154 default for applications distributed through the Chrome Web Store. To run | 97 :class: note |
| 155 Native Client applications that are not distributed through the Chrome Web | |
| 156 Store, e.g., applications that you build and run locally, you must | |
| 157 specifically enable the Native Client flag in Chrome.) | |
| 158 | 98 |
| 159 * Type ``about:flags`` in the Chrome address bar and scroll down to "Native | 99 To find out the version of Chrome, type ``about:chrome`` in the address bar. |
| 160 Client". | |
| 161 * If the link below "Native Client" says "Disable", then Native Client is | |
| 162 already enabled and you don't need to do anything else. | |
| 163 * If the link below "Native Client" says "Enable", click the "Enable" link, | |
| 164 scroll down to the bottom of the page, and click the "Relaunch Now" button. | |
| 165 All browser windows will restart when you relaunch Chrome. | |
| 166 | 100 |
| 167 c. Disable the Chrome cache. (Chrome caches resources aggressively; you should | 101 For a better development experience, it's also recommended to disable the |
| 168 disable the cache whenever you are developing a Native Client application in | 102 Chrome cache. Chrome caches resources aggressively; disabling the cache helps |
| 169 order to make sure Chrome loads new versions of your application.) | 103 make sure that the latest version of the Native Client module is loaded during |
| 104 development. | |
| 170 | 105 |
| 171 * Open Chrome's developer tools by clicking the menu icon |menu-icon| and | 106 * Open Chrome's developer tools by clicking the menu icon |menu-icon| and |
| 172 choosing Tools > Developer tools. | 107 choosing ``Tools > Developer tools``. |
| 173 * Click the gear icon |gear-icon| in the bottom right corner of the Chrome | 108 * Click the gear icon |gear-icon| in the bottom right corner of the Chrome |
| 174 window. | 109 window. |
| 175 * Under the "General" settings, check the box next to "Disable cache". | 110 * Under the "General" settings, check the box next to "Disable cache (while |
| 111 DevTools is open)". | |
| 112 * Keep the Developer Tools pane open while developing Native Client | |
| 113 applications. | |
| 176 | 114 |
| 177 .. |menu-icon| image:: /images/menu-icon.png | 115 .. |menu-icon| image:: /images/menu-icon.png |
| 178 .. |gear-icon| image:: /images/gear-icon.png | 116 .. |gear-icon| image:: /images/gear-icon.png |
| 179 | 117 |
| 180 Step 4: Create a set of stub files for your application | 118 Step 4: Stub code for the tutorial |
| 181 ======================================================= | 119 ================================== |
| 182 | 120 |
| 183 Create a set of stub files as follows: | 121 The stub code for the tutorial is avalable in the SDK, in |
| 122 ``pepper_$(VERSION)/getting_started/part1``. It contains the following files: | |
| 184 | 123 |
| 185 a. Download `hello_tutorial.zip | 124 * ``index.html``: Contains the HTML layout of the page as well as the JavaScript |
| 186 <https://developers.google.com/native-client/devguide/hello_tutorial.zip>`_. | 125 code that interacts with the Native Client module. |
| 187 | 126 |
| 188 b. Unzip hello_tutorial.zip: | 127 The Native Client module is included in the page with an ``<embed>`` tag that |
| 128 points to a manifest file. | |
| 129 * ``hello_tutorial.nmf``: A manifest file that's used to point the HTML to the | |
| 130 Native Client module and optionally provide additional commands to the PNaCl | |
| 131 translator that is part of the Chrome browser. | |
| 132 * ``hello_tutorial.cc``: C++ code for a simple Native Client module. | |
| 133 * ``Makefile``: Compilation commands to build the **pexe** (portable executable) | |
| 134 from the C++ code in ``hello_tutorial.cc``. | |
| 189 | 135 |
| 190 * On Mac/Linux, run the command "``unzip hello_tutorial.zip``" in a Terminal | 136 It's a good idea to take a look at these files now---they contain a large amount |
| 191 window. | 137 of comments that help explain their structure and contents. For more details |
| 192 * On Windows, right-click on the .zip file and select "Extract All..." A | 138 on the structure of a typical Native Client application, see |
| 193 dialog box will open; enter a location and click "Extract". | 139 :doc:`Application Structure <coding/application-structure>`. |
| 194 | 140 |
| 195 c. Unzipping hello_tutorial.zip creates a directory called ``hello_tutorial`` | 141 The stub code is intentionally very minimal. The C++ code does not do anything |
| 196 with the following files: | 142 except correctly initializing itself. The JavaScript code waits for the Native |
|
binji
2013/09/19 22:06:50
correctly initialize
eliben
2013/09/19 23:19:21
Done.
| |
| 197 | 143 Client module to load and changes the status text on the web page accordingly. |
| 198 * ``hello_tutorial.html`` | |
| 199 * ``hello_tutorial.cc`` | |
| 200 * ``hello_tutorial.nmf`` | |
| 201 * ``Makefile`` | |
| 202 * ``make.bat`` (for Windows) | |
| 203 | |
| 204 d. Move the ``hello_tutorial`` directory so that it's under the ``examples`` | |
| 205 directory where you started the local server. Its location should be, e.g., | |
| 206 ``pepper_28/examples/hello_tutorial``. | |
| 207 | |
| 208 * On Windows, depending on the location you entered when you unzipped the | |
| 209 file, there may be two ``hello_tutorial`` directories—one nested within | |
| 210 the other. Move only the inner (nested) directory to the ``examples`` | |
| 211 directory. | |
| 212 | |
| 213 .. Note:: | |
| 214 :class: note | |
| 215 | |
| 216 **Note regarding the location of project directories:** | |
| 217 | |
| 218 * In this tutorial, you are adding the ``hello_tutorial`` directory under the | |
| 219 ``examples`` directory because the ``examples`` directory is where your | |
| 220 local server is running, ready to serve your tutorial application. You can | |
| 221 place your project directory anywhere on your file system, as long as that | |
| 222 location is being served by your server. | |
| 223 * If you do place the ``hello_tutorial`` project directory in another | |
| 224 location, you must set the `environment variable | |
| 225 <http://en.wikipedia.org/wiki/Environment_variable>`_ ``NACL_SDK_ROOT`` to | |
| 226 point to the top-level directory of the bundle you are using (e.g., | |
| 227 ``<location-where-you-installed-the-SDK>/pepper_28``) in order for the | |
| 228 Makefile that's included in the project directory to work. | |
| 229 * If you use the location recommended above | |
| 230 (``pepper_28/examples/hello_tutorial``), be careful when you update the | |
| 231 SDK. The command '``naclsdk update pepper_28 --force``' will overwrite the | |
| 232 ``pepper_28`` directory, so move any project directories you want to keep | |
| 233 to another location. | |
| 234 | 144 |
| 235 Step 5: Compile the Native Client module and run the stub application | 145 Step 5: Compile the Native Client module and run the stub application |
| 236 ===================================================================== | 146 ===================================================================== |
| 237 | 147 |
| 238 The files you downloaded in the previous step constitute a stub application | 148 To compile the Native Client module, run ``make``: |
| 239 that simply loads a Native Client module into a web page and updates a | |
| 240 ``<div>`` element on the page with the status of the module load. | |
| 241 | |
| 242 To compile the Native Client module ``hello_tutorial.cc,`` run '``make``': | |
| 243 | 149 |
| 244 .. naclcode:: | 150 .. naclcode:: |
| 245 :prettyprint: 0 | 151 :prettyprint: 0 |
| 246 | 152 |
| 247 cd pepper_28/examples/hello_tutorial | 153 $ cd pepper_$(VERSION)/getting_started/part1 |
| 248 make | 154 $ make |
| 249 | 155 |
| 250 The '``make``' command runs the necessary compile and link commands to produce | 156 Since the sample is located within the SDK tree, the Makefile knows how to find |
| 251 three executable Native Client modules (for the x86-32, x86-64, and ARM | 157 the PNaCl toolchain automatically and use it to build the module. If you're |
| 252 architectures). The executable files are named as follows: | 158 building applications outside the NaCl SDK tree, you should set the |
| 159 ``$NACL_SDK_ROOT`` environment variable. See :doc:`Building Native Client | |
| 160 Modules <devcycle/building>` for more details. | |
| 253 | 161 |
| 254 * ``hello_tutorial_x86_32.nexe`` | 162 Assuming the local server was started according to the instructions in :ref:`Ste p 2 |
|
jvoung (off chromium)
2013/09/19 21:46:35
80 col
eliben
2013/09/19 23:19:21
Done.
| |
| 255 * ``hello_tutorial_x86_64.nexe`` | 163 <tutorial_step_2>`, you can now load the sample by pointing Chrome to |
| 256 * ``hello_tutorial_arm.nexe`` | 164 http://localhost:5103/part1. Chrome should load the Native Client module |
| 165 successfully and the Status text should change from "LOADING..." to "SUCCESS". | |
|
binji
2013/09/19 22:06:50
Probably need a troubleshooting. What happens if I
eliben
2013/09/19 23:19:21
OK, will add a link to Troubleshooting
| |
| 257 | 166 |
| 258 Assuming you are using the local server and the project directory specified | 167 Step 6: Modify the JavaScript code to send a message to the Native Client module |
| 259 above, you can load the ``hello_tutorial.html`` web page into Chrome by visiting | 168 ================================================================================ |
| 260 the following URL: http://localhost:5103/hello_tutorial/hello_tutorial.html. If | |
| 261 Chrome loads the Native Client module successfully, the Status display on the | |
| 262 page should change from "LOADING..." to "SUCCESS". | |
| 263 | 169 |
| 264 Step 6: Review the code in the stub application | 170 In this step, you'll modify the web page (``index.html``) to send a message to |
| 265 =============================================== | 171 the Native Client module after the page loads the module. |
| 266 | 172 |
| 267 The section highlights some of the code in the stub application. | 173 Look for the JavaScript function ``moduleDidLoad()``, and add new code to send |
| 174 a 'hello' message to the module. The new function should look as follows: | |
| 268 | 175 |
| 269 Makefile | 176 .. naclcode:: |
| 270 ``Makefile`` contains the compile and link commands to build the executable | |
| 271 Native Client modules (.nexe files) for your application. The Native Client | |
| 272 SDK includes multiple GCC‑based toolchains to build modules for multiple | |
| 273 architectures (x86 and ARM) using different implementations of the C library | |
| 274 (`newlib <http://www.sourceware.org/newlib/>`_ and `glibc | |
| 275 <http://www.gnu.org/software/libc/>`_). The commands in the tutorial | |
| 276 ``Makefile`` build the application using the newlib C library for the x86 and | |
| 277 ARM architectures. The commands use the toolchains located in the | |
| 278 ``pepper_28/toolchain/<platform>_x86_newlib`` and ``<platform>_arm_newlib`` | |
| 279 directories. For information about how to use Makefiles and the '``make``' | |
| 280 command, see the `GNU 'make' manual | |
| 281 <http://www.gnu.org/software/make/manual/make.html>`_. | |
| 282 | 177 |
| 283 hello_tutorial.nmf | 178 function moduleDidLoad() { |
| 284 ``hello_tutorial.nmf`` is a Native Client manifest file that tells Chrome | 179 HelloTutorialModule = document.getElementById('hello_tutorial'); |
|
jvoung (off chromium)
2013/09/19 21:46:35
should this JS have "var"
binji
2013/09/19 22:06:50
Nope, it's global. :)
eliben
2013/09/19 23:19:21
F* JS
| |
| 285 which compiled Native Client module (.nexe) to load based on the instruction | 180 updateStatus('SUCCESS'); |
| 286 set architecture of the user's machine (e.g., x86-32, x86-64, or ARM). For | 181 // Send a message to the Native Client module |
| 287 applications compiled using glibc, manifest files must also specify the | 182 HelloTutorialModule.postMessage('hello'); |
| 288 shared libraries that the applications use. | 183 } |
| 289 | 184 |
| 290 hello_tutorial.html | 185 Step 7: Implement a message handler in the Native Client module |
| 291 ``hello_tutorial.html`` is the web page that corresponds to your application. | |
| 292 The page includes an ``<embed>`` element that loads the compiled Native | |
| 293 Client module: | |
| 294 | |
| 295 .. naclcode:: | |
| 296 | |
| 297 <div id="listener"> | |
| 298 <script type="text/javascript"> | |
| 299 var listener = document.getElementById('listener'); | |
| 300 listener.addEventListener('load', moduleDidLoad, true); | |
| 301 listener.addEventListener('message', handleMessage, true); | |
| 302 </script> | |
| 303 | |
| 304 <embed name="nacl_module" | |
| 305 id="hello_tutorial" | |
| 306 width=0 height=0 | |
| 307 src="hello_tutorial.nmf" | |
| 308 type="application/x-nacl" /> | |
| 309 </div> | |
| 310 | |
| 311 The ``src`` attribute in the ``<embed>`` element points to the Native Client | |
| 312 manifest file, which tells the browser which .nexe file to load based on the | |
| 313 instruction set architecture of the user's machine. The ``width`` and | |
| 314 ``height`` attributes in the ``<embed>`` element are set to 0 because the | |
| 315 Native Client module in this example does not have any graphical component. | |
| 316 The ``type`` attribute declares the MIME type to be ``x-nacl``, i.e., an | |
| 317 executable Native Client module. | |
| 318 | |
| 319 The ``<embed>`` element is wrapped inside a ``<div>`` element that has two | |
| 320 event listeners attached—one for the 'load' event, which fires when the | |
| 321 browser successfully loads the Native Client module, and one for the | |
| 322 'message' event, which fires when the Native Client module uses the | |
| 323 ``PostMessage()`` method (in the `pp::Instance | |
| 324 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance>`_ | |
| 325 class) to send a message to the JavaScript code in the application. This | |
| 326 technique of attaching the event listeners to a parent ``<div>`` element | |
| 327 (rather than directly to the ``<embed>`` element) is used to ensure that the | |
| 328 event listeners are active before the module 'load' event fires. | |
| 329 | |
| 330 The simple event handlers in this tutorial are implemented in the | |
| 331 ``moduleDidLoad()`` and ``handleMessage()`` JavaScript functions. | |
| 332 ``moduleDidLoad()`` changes the text inside the 'status_field' ``<div>`` | |
| 333 element. handleMessage() displays the content of messages sent from the | |
| 334 Native Client module in a browser alert panel. For a description of 'load', | |
| 335 'message', and other Native Client events, see the :doc:`Progress Events | |
| 336 <coding/progress-events>` chapter of the Developer's Guide. | |
| 337 | |
| 338 hello_tutorial.cc | |
| 339 Native Client includes the concept of modules and instances: | |
| 340 | |
| 341 * A **module** is C or C++ code compiled into an executable .nexe file. | |
| 342 * An **instance** is a rectangle on a web page that is managed by a module. | |
| 343 The rectangle can have dimensions 0x0, in which case the instance does not | |
| 344 have a visual component on the web page. An instance is created by | |
| 345 including an ``<embed>`` element in a web page. A module may be included in | |
| 346 a web page multiple times by using multiple ``<embed>`` elements that refer | |
| 347 to the module; in this case the Native Client runtime system loads the | |
| 348 module once and creates multiple instances that are managed by the module. | |
| 349 | |
| 350 The example in this tutorial includes one module | |
| 351 (``hello_tutorial_x86_32.nexe``, ``hello_tutorial_x86_64.nexe``, or | |
| 352 ``hello_tutorial_arm.nexe``, depending on the instruction set architecture of | |
| 353 the user's machine), and one instance (one ``<embed>`` element that loads the | |
| 354 module). The source code for the module is in the file ``hello_tutorial.cc``. | |
| 355 This source code contains the minimum code required in a C++ Native Client | |
| 356 module—an implementation of the `Instance | |
| 357 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance>`_ | |
| 358 and `Module | |
| 359 <https://developers.google.com/native-client/peppercpp/classpp_1_1_module>`_ | |
| 360 classes. These implementations don't actually do anything yet. | |
| 361 | |
| 362 Step 7: Modify the web page to send a message to the Native Client module | |
| 363 ========================================================================= | |
| 364 | |
| 365 In this step, you'll modify the web page (``hello_tutorial.html``) to send a | |
| 366 message to the Native Client module after the page loads the module. | |
| 367 | |
| 368 Look for the JavaScript function ``moduleDidLoad()``, and add the new code below | |
| 369 (indicated by boldface type) to send a 'hello' message to the Native Client | |
| 370 module: | |
| 371 | |
| 372 ..naclcode:: | |
| 373 | |
| 374 function moduleDidLoad() { | |
| 375 HelloTutorialModule = document.getElementById('hello_tutorial'); | |
| 376 updateStatus('SUCCESS'); | |
| 377 // Send a message to the NaCl module. | |
| 378 HelloTutorialModule.postMessage('hello'); | |
| 379 } | |
| 380 | |
| 381 Step 8: Implement a message handler in the Native Client module | |
| 382 =============================================================== | 186 =============================================================== |
| 383 | 187 |
| 384 In this step, you'll modify the Native Client module (``hello_tutorial.cc``) to | 188 In this step, you'll modify the Native Client module (``hello_tutorial.cc``) to |
| 385 respond to the message received from the JavaScript code in the application. | 189 respond to the message received from the JavaScript code in the application. |
| 386 Specifically, you'll: | 190 Specifically, you'll: |
| 387 | 191 |
| 388 * implement the ``HandleMessage()`` function for the module, and | 192 * Implement the ``HandleMessage()`` method of the module instance. |
|
binji
2013/09/19 22:06:50
Actually I think C++ people prefer "member functio
eliben
2013/09/19 23:19:21
good point. will change to member function to be m
| |
| 389 * use the ``PostMessage()`` function to send a message from the module to the | 193 * Use the ``PostMessage()`` method to send a message from the module to the |
| 390 JavaScript code | 194 JavaScript code. |
| 391 | 195 |
| 392 First, add code to define the variables used by the Native Client module (the | 196 First, add code to define the variables used by the Native Client module (the |
| 393 'hello' string you're expecting to receive from JavaScript and the reply string | 197 'hello' string you're expecting to receive from JavaScript and the reply string |
| 394 you want to return to JavaScript as a response). In the file | 198 you want to return to JavaScript as a response). In the file |
| 395 ``hello_tutorial.cc``, add this code after the ``#include`` statements: | 199 ``hello_tutorial.cc``, add this code after the ``#include`` statements: |
| 396 | 200 |
| 397 .. naclcode:: | 201 .. naclcode:: |
| 398 | 202 |
| 399 namespace { | 203 namespace { |
| 400 // The expected string sent by the browser. | 204 // The expected string sent by the browser. |
| 401 const char* const kHelloString = "hello"; | 205 const char* const kHelloString = "hello"; |
| 402 // The string sent back to the browser upon receipt of a message | 206 // The string sent back to the browser upon receipt of a message |
| 403 // containing "hello". | 207 // containing "hello". |
| 404 const char* const kReplyString = "hello from NaCl"; | 208 const char* const kReplyString = "hello from NaCl"; |
| 405 } // namespace | 209 } // namespace |
| 406 | 210 |
| 407 Now, implement the ``HandleMessage()`` method to check for ``kHelloString`` and | 211 Now, implement the ``HandleMessage()`` method to check for ``kHelloString`` and |
| 408 return ``kReplyString.`` Look for the following line: | 212 return ``kReplyString.`` Look for the following line: |
| 409 | 213 |
| 410 .. naclcode:: | 214 .. naclcode:: |
| 411 | 215 |
| 412 // TODO(sdk_user): 1. Make this function handle the incoming message. | 216 // TODO(sdk_user): 1. Make this function handle the incoming message. |
| 413 | 217 |
| 414 Replace the above line with the boldface code below: | 218 Populate the method with code, as follows: |
| 415 | 219 |
| 416 .. naclcode:: | 220 .. naclcode:: |
| 417 | 221 |
| 418 virtual void HandleMessage(const pp::Var& var_message) { | 222 virtual void HandleMessage(const pp::Var& var_message) { |
| 419 if (!var_message.is_string()) | 223 if (!var_message.is_string()) |
| 420 return; | 224 return; |
| 421 std::string message = var_message.AsString(); | 225 std::string message = var_message.AsString(); |
| 422 pp::Var var_reply; | 226 pp::Var var_reply; |
| 423 if (message == kHelloString) { | 227 if (message == kHelloString) { |
| 424 var_reply = pp::Var(kReplyString); | 228 var_reply = pp::Var(kReplyString); |
| 425 PostMessage(var_reply); | 229 PostMessage(var_reply); |
| 426 } | 230 } |
| 427 } | 231 } |
| 428 | 232 |
| 429 See the Pepper API documentation for additional information about the | 233 See the Pepper API documentation for additional information about the |
| 430 `pp::Instance.HandleMessage | 234 `pp::Instance.HandleMessage |
| 431 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a5dce8c8b36b1df7cfcc12e42397a35e8>`_ | 235 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a5dce8c8b36b1df7cfcc12e42397a35e8>`_ |
|
jvoung (off chromium)
2013/09/19 21:46:35
hope the hashes are stable =)
eliben
2013/09/19 23:19:21
I'm sure they are ;-)
| |
| 432 and `pp::Instance.PostMessage | 236 and `pp::Instance.PostMessage |
| 433 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a67e888a4e4e23effe7a09625e73ecae9>`_ | 237 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a67e888a4e4e23effe7a09625e73ecae9>`_ |
| 434 methods. | 238 methods. |
| 435 | 239 |
| 436 Step 9: Compile the Native Client module and run the application again | 240 Step 8: Compile the Native Client module and run the application again |
| 437 ====================================================================== | 241 ====================================================================== |
| 438 | 242 |
| 439 Compile the Native Client module by running the '``make``' command again. | 243 Compile the Native Client module by running the ``make`` command again. |
| 440 | 244 |
| 441 Run the application by reloading hello_tutorial.html in Chrome. (The page | 245 Re-run the application by reloading http://localhost:5103/part1 in Chrome. |
| 442 should be at http://localhost:5103/hello_tutorial/hello_tutorial.html assuming | |
| 443 the setup described above.) | |
| 444 | 246 |
| 445 After Chrome loads the Native Client module, you should see an alert panel | 247 After Chrome loads the Native Client module, you should see an alert panel |
| 446 appear with the message sent from the module. | 248 appear with the message sent from the module. |
| 447 | 249 |
| 448 Troubleshooting | 250 Troubleshooting |
| 449 =============== | 251 =============== |
| 450 | 252 |
| 451 If your application doesn't run, see :ref:`Step 3 <step_3>` above | 253 If your application doesn't run, see :ref:`Step 3 <tutorial_step_3>` above to |
| 452 to verify that you've set up your environment correctly, including both the | 254 verify that you've set up your environment correctly, including both the Chrome |
| 453 Chrome browser and the local server. Make sure that you're running a version of | 255 browser and the local server. Make sure that you're running a correct version of |
| 454 Chrome that is equal to or greater than the SDK bundle version you are using, | 256 Chrome, which is also greater or equal than the SDK bundle version you are |
| 455 that you've enabled the Native Client flag and relaunched Chrome, that you've | 257 using. |
|
jvoung (off chromium)
2013/09/19 21:46:35
Do we have docs on what the chrome console prints
eliben
2013/09/19 23:19:21
No. We should. Now who would be the best person to
jvoung (off chromium)
2013/09/19 23:29:53
I hear that ncbray has sent many emails describing
| |
| 456 disabled the Chrome cache, and that **you're accessing your application from a | |
| 457 local web server (rather than by dragging the HTML file into your browser)**. | |
| 458 | 258 |
| 459 For additional troubleshooting information, check the `FAQ | 259 For additional troubleshooting information, check the `FAQ |
| 460 <https://developers.google.com/native-client/faq.html#HangOnLoad>`_. | 260 <https://developers.google.com/native-client/faq.html#HangOnLoad>`_. |
| 461 | 261 |
| 262 TODO: more troubleshooting w.r.t. buildling/running make? | |
| 263 | |
| 462 Next steps | 264 Next steps |
| 463 ========== | 265 ========== |
| 464 | 266 |
| 465 * See the :doc:`Application Structure <coding/application-structure>` | 267 * See the :doc:`Application Structure <coding/application-structure>` |
| 466 chapter in the Developer's Guide for information about how to structure a | 268 chapter in the Developer's Guide for information about how to structure a |
| 467 Native Client module. | 269 Native Client module. |
| 468 * Check the `C++ Reference | 270 * Check the `C++ Reference |
| 469 <https://developers.google.com/native-client/peppercpp>`_ for details about | 271 <https://developers.google.com/native-client/peppercpp>`_ for details about |
| 470 how to use the Pepper APIs. | 272 how to use the Pepper APIs. |
| 471 * Browse through the source code of the SDK examples (in the ``examples`` | 273 * Browse through the source code of the SDK examples (in the ``examples`` |
| 472 directory) to learn additional techniques for writing Native Client | 274 directory) to learn additional techniques for writing Native Client |
| 473 applications and using the Pepper APIs. | 275 applications and using the Pepper APIs. |
| 474 * See the :doc:`Building <devcycle/building>`, :doc:`Running | 276 * See the :doc:`Building <devcycle/building>`, :doc:`Running |
| 475 <devcycle/running>`, and :doc:`Debugging pages <devcycle/debugging>` | 277 <devcycle/running>`, and :doc:`Debugging pages <devcycle/debugging>` |
| 476 for information about how to build, run, and debug Native Client | 278 for information about how to build, run, and debug Native Client |
| 477 applications. | 279 applications. |
| 478 * Check the `naclports <http://code.google.com/p/naclports/>`_ project to see | 280 * Check the `naclports <http://code.google.com/p/naclports/>`_ project to see |
| 479 what libraries have been ported for use with Native Client. If you port an | 281 what libraries have been ported for use with Native Client. If you port an |
| 480 open-source library for your own use, we recommend adding it to naclports | 282 open-source library for your own use, we recommend adding it to naclports |
| 481 (see `How to check code into naclports | 283 (see `How to check code into naclports |
| 482 <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_). | 284 <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_). |
| OLD | NEW |