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 Client module (C/C++ code). Both sides can initiate |
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? | |
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. |
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 initialize itself. The JavaScript code waits for the Native |
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 |
255 * ``hello_tutorial_x86_64.nexe`` | 163 :ref:`Step 2 <tutorial_step_2>`, you can now load the sample by pointing Chrome |
256 * ``hello_tutorial_arm.nexe`` | 164 to http://localhost:5103/part1. Chrome should load the Native Client module |
165 successfully and the Status text should change from "LOADING..." to "SUCCESS". | |
166 If you run into problems, check out the :ref:`Troubleshooting section | |
167 <tutorial_troubleshooting>` below. | |
257 | 168 |
258 Assuming you are using the local server and the project directory specified | 169 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 | 170 ================================================================================ |
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 | 171 |
264 Step 6: Review the code in the stub application | 172 In this step, you'll modify the web page (``index.html``) to send a message to |
265 =============================================== | 173 the Native Client module after the page loads the module. |
266 | 174 |
267 The section highlights some of the code in the stub application. | 175 Look for the JavaScript function ``moduleDidLoad()``, and add new code to send |
268 | 176 a 'hello' message to the module. The new function should look as follows: |
269 Makefile | |
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 | |
283 hello_tutorial.nmf | |
284 ``hello_tutorial.nmf`` is a Native Client manifest file that tells Chrome | |
285 which compiled Native Client module (.nexe) to load based on the instruction | |
286 set architecture of the user's machine (e.g., x86-32, x86-64, or ARM). For | |
287 applications compiled using glibc, manifest files must also specify the | |
288 shared libraries that the applications use. | |
289 | |
290 hello_tutorial.html | |
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 | 177 |
372 .. naclcode:: | 178 .. naclcode:: |
373 | 179 |
374 function moduleDidLoad() { | 180 function moduleDidLoad() { |
375 HelloTutorialModule = document.getElementById('hello_tutorial'); | 181 HelloTutorialModule = document.getElementById('hello_tutorial'); |
376 updateStatus('SUCCESS'); | 182 updateStatus('SUCCESS'); |
377 // Send a message to the NaCl module. | 183 // Send a message to the Native Client module |
378 HelloTutorialModule.postMessage('hello'); | 184 HelloTutorialModule.postMessage('hello'); |
379 } | 185 } |
380 | 186 |
381 Step 8: Implement a message handler in the Native Client module | 187 Step 7: Implement a message handler in the Native Client module |
382 =============================================================== | 188 =============================================================== |
383 | 189 |
384 In this step, you'll modify the Native Client module (``hello_tutorial.cc``) to | 190 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. | 191 respond to the message received from the JavaScript code in the application. |
386 Specifically, you'll: | 192 Specifically, you'll: |
387 | 193 |
388 * implement the ``HandleMessage()`` function for the module, and | 194 * Implement the ``HandleMessage()`` member function of the module instance. |
389 * use the ``PostMessage()`` function to send a message from the module to the | 195 * Use the ``PostMessage()`` member function to send a message from the module to |
390 JavaScript code | 196 the JavaScript code. |
391 | 197 |
392 First, add code to define the variables used by the Native Client module (the | 198 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 | 199 '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 | 200 you want to return to JavaScript as a response). In the file |
395 ``hello_tutorial.cc``, add this code after the ``#include`` statements: | 201 ``hello_tutorial.cc``, add this code after the ``#include`` statements: |
396 | 202 |
397 .. naclcode:: | 203 .. naclcode:: |
398 | 204 |
399 namespace { | 205 namespace { |
400 // The expected string sent by the browser. | 206 // The expected string sent by the browser. |
401 const char* const kHelloString = "hello"; | 207 const char* const kHelloString = "hello"; |
402 // The string sent back to the browser upon receipt of a message | 208 // The string sent back to the browser upon receipt of a message |
403 // containing "hello". | 209 // containing "hello". |
404 const char* const kReplyString = "hello from NaCl"; | 210 const char* const kReplyString = "hello from NaCl"; |
405 } // namespace | 211 } // namespace |
406 | 212 |
407 Now, implement the ``HandleMessage()`` method to check for ``kHelloString`` and | 213 Now, implement the ``HandleMessage()`` member function to check for |
408 return ``kReplyString.`` Look for the following line: | 214 ``kHelloString`` and return ``kReplyString.`` Look for the following line: |
409 | 215 |
410 .. naclcode:: | 216 .. naclcode:: |
411 | 217 |
412 // TODO(sdk_user): 1. Make this function handle the incoming message. | 218 // TODO(sdk_user): 1. Make this function handle the incoming message. |
413 | 219 |
414 Replace the above line with the boldface code below: | 220 Populate the member function with code, as follows: |
415 | 221 |
416 .. naclcode:: | 222 .. naclcode:: |
417 | 223 |
418 virtual void HandleMessage(const pp::Var& var_message) { | 224 virtual void HandleMessage(const pp::Var& var_message) { |
419 if (!var_message.is_string()) | 225 if (!var_message.is_string()) |
420 return; | 226 return; |
421 std::string message = var_message.AsString(); | 227 std::string message = var_message.AsString(); |
422 pp::Var var_reply; | 228 pp::Var var_reply; |
423 if (message == kHelloString) { | 229 if (message == kHelloString) { |
424 var_reply = pp::Var(kReplyString); | 230 var_reply = pp::Var(kReplyString); |
425 PostMessage(var_reply); | 231 PostMessage(var_reply); |
426 } | 232 } |
427 } | 233 } |
428 | 234 |
429 See the Pepper API documentation for additional information about the | 235 See the Pepper API documentation for additional information about the |
430 `pp::Instance.HandleMessage | 236 `pp::Instance.HandleMessage |
431 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a5dce8c8b36b1df7cfcc12e42397a35e8>`_ | 237 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a5dce8c8b36b1df7cfcc12e42397a35e8>`_ |
432 and `pp::Instance.PostMessage | 238 and `pp::Instance.PostMessage |
433 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a67e888a4e4e23effe7a09625e73ecae9>`_ | 239 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a67e888a4e4e23effe7a09625e73ecae9>`_ |
434 methods. | 240 member functions. |
435 | 241 |
436 Step 9: Compile the Native Client module and run the application again | 242 Step 8: Compile the Native Client module and run the application again |
437 ====================================================================== | 243 ====================================================================== |
438 | 244 |
439 Compile the Native Client module by running the '``make``' command again. | 245 Compile the Native Client module by running the ``make`` command again. |
440 | 246 |
441 Run the application by reloading hello_tutorial.html in Chrome. (The page | 247 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 | 248 |
445 After Chrome loads the Native Client module, you should see an alert panel | 249 After Chrome loads the Native Client module, you should see an alert panel |
446 appear with the message sent from the module. | 250 appear with the message sent from the module. |
447 | 251 |
252 .. _tutorial_troubleshooting: | |
253 | |
448 Troubleshooting | 254 Troubleshooting |
449 =============== | 255 =============== |
450 | 256 |
451 If your application doesn't run, see :ref:`Step 3 <step_3>` above | 257 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 | 258 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 | 259 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, | 260 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 | 261 using. |
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 | 262 |
459 For additional troubleshooting information, check the `FAQ | 263 Another useful debugging aid is the Chrome JavaScript console (available via the |
460 <https://developers.google.com/native-client/faq.html#HangOnLoad>`_. | 264 ``Tools`` menu or by pressing ``Shift+Ctrl+J``). Examine it for clues about what |
binji
2013/09/20 17:14:44
The command is different on Mac as well (Shift+Cmd
| |
265 went wrong. For example, if there's a message saying "NaCl module crashed", | |
266 there is a possibility that the Native Client module has a bug; | |
267 :doc:`debugging <devcycle/debugging>` may be required. | |
268 | |
269 There's more information about troubleshooting in the documentation: | |
270 | |
271 * `FAQ <https://developers.google.com/native-client/faq.html#HangOnLoad>`_. | |
272 * The :doc:`Progress Events <coding/progress-events>` document contains some | |
273 useful information about handling error events. | |
274 | |
275 .. TODO: fix FAQ link and others to :ref:/:doc: once ReST-ified. | |
461 | 276 |
462 Next steps | 277 Next steps |
463 ========== | 278 ========== |
464 | 279 |
465 * See the :doc:`Application Structure <coding/application-structure>` | 280 * See the :doc:`Application Structure <coding/application-structure>` |
466 chapter in the Developer's Guide for information about how to structure a | 281 chapter in the Developer's Guide for information about how to structure a |
467 Native Client module. | 282 Native Client module. |
468 * Check the `C++ Reference | 283 * Check the `C++ Reference |
469 <https://developers.google.com/native-client/peppercpp>`_ for details about | 284 <https://developers.google.com/native-client/peppercpp>`_ for details about |
470 how to use the Pepper APIs. | 285 how to use the Pepper APIs. |
471 * Browse through the source code of the SDK examples (in the ``examples`` | 286 * Browse through the source code of the SDK examples (in the ``examples`` |
472 directory) to learn additional techniques for writing Native Client | 287 directory) to learn additional techniques for writing Native Client |
473 applications and using the Pepper APIs. | 288 applications and using the Pepper APIs. |
474 * See the :doc:`Building <devcycle/building>`, :doc:`Running | 289 * See the :doc:`Building <devcycle/building>`, :doc:`Running |
475 <devcycle/running>`, and :doc:`Debugging pages <devcycle/debugging>` | 290 <devcycle/running>`, and :doc:`Debugging pages <devcycle/debugging>` |
476 for information about how to build, run, and debug Native Client | 291 for information about how to build, run, and debug Native Client |
477 applications. | 292 applications. |
478 * Check the `naclports <http://code.google.com/p/naclports/>`_ project to see | 293 * 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 | 294 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 | 295 open-source library for your own use, we recommend adding it to naclports |
481 (see `How to check code into naclports | 296 (see `How to check code into naclports |
482 <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_). | 297 <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_). |
OLD | NEW |