3 ######################################
4 C++ Tutorial: Getting Started (Part 1)
5 ######################################
15 This tutorial shows how to build and run a web application using Portable Native
16 Client (PNaCl). This is a client-side application that uses HTML, JavaScript and
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.
20 It's recommended to read the :doc:`Native Client Technical Overview
21 </overview>` prior to going through this tutorial.
23 What the application in this tutorial does
24 ------------------------------------------
26 The application in this tutorial shows how to load a Native Client module in a
27 web page, and how to send messages between JavaScript and the C++ code in the
28 Native Client module. In this simple application, the JavaScript code in the web
29 page sends a ``'hello'`` message to the Native Client module. When the Native
30 Client module receives a message, it checks whether the message is equal to the
31 string ``'hello'``. If it is, the Native Client module returns a message saying
32 ``'hello from NaCl'``. A JavaScript alert panel displays the message received
33 from the Native Client module.
35 Communication between JavaScript and Native Client modules
36 ----------------------------------------------------------
38 The Native Client programming model supports bidirectional communication between
39 JavaScript and the Native Client module (C/C++ code). Both sides can initiate
40 and respond to messages. In all cases, the communication is asynchronous: The
41 caller (JavaScript or the Native Client module) sends a message, but the caller
42 does not wait for, or may not even expect, a response. This behavior is
43 analogous to client/server communication on the web, where the client posts a
44 message to the server and returns immediately. The Native Client messaging
45 system is part of the Pepper API, and is described in detail in
46 :doc:`Developer's Guide: Messaging System </devguide/coding/message-system>`.
47 It is also similar to the way `web workers
48 <http://en.wikipedia.org/wiki/Web_worker>`_ interact with the main document in
51 Step 1: Download and install the Native Client SDK
52 ==================================================
54 Follow the instructions on the :doc:`Download </sdk/download>` page to
55 download and install the Native Client SDK.
59 Step 2: Start a local server
60 ============================
62 To simulate a production environment, the SDK provides a simple web server that
63 can be used to serve the application on ``localhost``. A convenience Makefile
64 rule called ``serve`` is the easiest way to invoke it:
69 $ cd pepper_$(VERSION)/getting_started
75 The SDK may consist of several "bundles", one per Chrome/Pepper version (see
76 :doc:`versioning information </version>`). In the sample invocation above
77 ``pepper_$(VERSION)`` refers to the specific version you want to use. For
78 example, ``pepper_31``. If you don't know which version you need, use the
79 one labeled ``(stable)`` by ``naclsdk list``. See :doc:`Download the Native
80 Client SDK </sdk/download>` for more details.
82 If no port number is specified, the server defaults to port 5103, and can be
83 accessed at ``http://localhost:5103``.
85 Any server can be used for the purpose of development. The one provided with the
86 SDK is just a convenience, not a requirement.
90 Step 3: Set up the Chrome browser
91 =================================
93 PNaCl is enabled by default in Chrome version 31 and later. Please make sure
94 that you have a suitable version to work through this tutorial. It's also
95 important to use a Chrome version that's the same or newer than the SDK bundle
96 used to build the Native Client modules.
101 To find out the version of Chrome, type ``about:chrome`` in the address bar.
103 For a better development experience, it's also recommended to disable the
104 Chrome cache. Chrome caches resources aggressively; disabling the cache helps
105 make sure that the latest version of the Native Client module is loaded during
108 * Open Chrome's developer tools by clicking the menu icon |menu-icon| and
109 choosing ``Tools > Developer tools``.
110 * Click the gear icon |gear-icon| in the bottom right corner of the Chrome
112 * Under the "General" settings, check the box next to "Disable cache (while
114 * Keep the Developer Tools pane open while developing Native Client
117 .. |menu-icon| image:: /images/menu-icon.png
118 .. |gear-icon| image:: /images/gear-icon.png
120 Step 4: Stub code for the tutorial
121 ==================================
123 The stub code for the tutorial is avalable in the SDK, in
124 ``pepper_$(VERSION)/getting_started/part1``. It contains the following files:
126 * ``index.html``: Contains the HTML layout of the page as well as the JavaScript
127 code that interacts with the Native Client module.
129 The Native Client module is included in the page with an ``<embed>`` tag that
130 points to a manifest file.
131 * ``hello_tutorial.nmf``: A manifest file that's used to point the HTML to the
132 Native Client module and optionally provide additional commands to the PNaCl
133 translator that is part of the Chrome browser.
134 * ``hello_tutorial.cc``: C++ code for a simple Native Client module.
135 * ``Makefile``: Compilation commands to build the **pexe** (portable executable)
136 from the C++ code in ``hello_tutorial.cc``.
138 It's a good idea to take a look at these files now---they contain a large amount
139 of comments that help explain their structure and contents. For more details
140 on the structure of a typical Native Client application, see
141 :doc:`Application Structure </devguide/coding/application-structure>`.
143 The stub code is intentionally very minimal. The C++ code does not do anything
144 except correctly initialize itself. The JavaScript code waits for the Native
145 Client module to load and changes the status text on the web page accordingly.
149 Step 5: Compile the Native Client module and run the stub application
150 =====================================================================
152 To compile the Native Client module, run ``make``:
157 $ cd pepper_$(VERSION)/getting_started/part1
160 Since the sample is located within the SDK tree, the Makefile knows how to find
161 the PNaCl toolchain automatically and use it to build the module. If you're
162 building applications outside the NaCl SDK tree, you should set the
163 ``$NACL_SDK_ROOT`` environment variable. See :doc:`Building Native Client
164 Modules </devguide//devcycle/building>` for more details.
166 Assuming the local server was started according to the instructions in
167 :ref:`Step 2 <tutorial_step_2>`, you can now load the sample by pointing Chrome
168 to ``http://localhost:5103/part1``. Chrome should load the Native Client module
169 successfully and the Status text should change from "LOADING..." to "SUCCESS".
170 If you run into problems, check out the :ref:`Troubleshooting section
171 <tutorial_troubleshooting>` below.
173 Step 6: Modify the JavaScript code to send a message to the Native Client module
174 ================================================================================
176 In this step, you'll modify the web page (``index.html``) to send a message to
177 the Native Client module after the page loads the module.
179 Look for the JavaScript function ``moduleDidLoad()``, and add new code to send
180 a 'hello' message to the module. The new function should look as follows:
184 function moduleDidLoad() {
185 HelloTutorialModule = document.getElementById('hello_tutorial');
186 updateStatus('SUCCESS');
187 // Send a message to the Native Client module
188 HelloTutorialModule.postMessage('hello');
191 Step 7: Implement a message handler in the Native Client module
192 ===============================================================
194 In this step, you'll modify the Native Client module (``hello_tutorial.cc``) to
195 respond to the message received from the JavaScript code in the application.
196 Specifically, you'll:
198 * Implement the ``HandleMessage()`` member function of the module instance.
199 * Use the ``PostMessage()`` member function to send a message from the module to
202 First, add code to define the variables used by the Native Client module (the
203 'hello' string you're expecting to receive from JavaScript and the reply string
204 you want to return to JavaScript as a response). In the file
205 ``hello_tutorial.cc``, add this code after the ``#include`` statements:
210 // The expected string sent by the browser.
211 const char* const kHelloString = "hello";
212 // The string sent back to the browser upon receipt of a message
213 // containing "hello".
214 const char* const kReplyString = "hello from NaCl";
217 Now, implement the ``HandleMessage()`` member function to check for
218 ``kHelloString`` and return ``kReplyString.`` Look for the following line:
222 // TODO(sdk_user): 1. Make this function handle the incoming message.
224 Populate the member function with code, as follows:
228 virtual void HandleMessage(const pp::Var& var_message) {
229 if (!var_message.is_string())
231 std::string message = var_message.AsString();
233 if (message == kHelloString) {
234 var_reply = pp::Var(kReplyString);
235 PostMessage(var_reply);
239 See the Pepper API documentation for additional information about the
240 `pp::Instance.HandleMessage
241 </native-client/pepper_stable/cpp/classpp_1_1_instance.html#a5dce8c8b36b1df7cfcc12e42397a35e8>`_
242 and `pp::Instance.PostMessage
243 </native-client/pepper_stable/cpp/classpp_1_1_instance.html#a67e888a4e4e23effe7a09625e73ecae9>`_
246 Step 8: Compile the Native Client module and run the application again
247 ======================================================================
249 Compile the Native Client module by running the ``make`` command again.
251 Re-run the application by reloading ``http://localhost:5103/part1`` in Chrome.
253 After Chrome loads the Native Client module, you should see an alert panel
254 appear with the message sent from the module.
256 .. _tutorial_troubleshooting:
261 If your application doesn't run, see :ref:`Step 3 <tutorial_step_3>` above to
262 verify that you've set up your environment correctly, including both the Chrome
263 browser and the local server. Make sure that you're running a correct version of
264 Chrome, which is also greater or equal than the SDK bundle version you are
267 Another useful debugging aid is the Chrome JavaScript console (available via the
268 ``Tools`` menu in Chrome). Examine it for clues about what went wrong. For
269 example, if there's a message saying "NaCl module crashed", there is a
270 possibility that the Native Client module has a bug; :doc:`debugging
271 </devguide/devcycle/debugging>` may be required.
273 There's more information about troubleshooting in the documentation:
275 * :ref:`FAQ Troubleshooting <faq_troubleshooting>`.
276 * The :doc:`Progress Events </devguide/coding/progress-events>` document
277 contains some useful information about handling error events.
282 * See the :doc:`Application Structure </devguide/coding/application-structure>`
283 chapter in the Developer's Guide for information about how to structure a
284 Native Client module.
285 * Check the `C++ Reference </native-client/pepper_stable/cpp>`_ for details
286 about how to use the Pepper APIs.
287 * Browse through the source code of the SDK examples (in the ``examples``
288 directory) to learn additional techniques for writing Native Client
289 applications and using the Pepper APIs.
290 * See the :doc:`Building </devguide/devcycle/building>`, :doc:`Running
291 </devguide/devcycle/running>`, and :doc:`Debugging pages
292 </devguide/devcycle/debugging>` for information about how to build, run, and
293 debug Native Client applications.
294 * Check the `naclports <http://code.google.com/p/naclports/>`_ project to see
295 what libraries have been ported for use with Native Client. If you port an
296 open-source library for your own use, we recommend adding it to naclports
297 (see `How to check code into naclports
298 <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_).