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 that you 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 Native Client
28 module. In this simple application, the JavaScript sends a ``'hello'`` message
29 to the Native Client module. When the Native Client module receives a message,
30 it checks whether the message is equal to the string ``'hello'``. If it is, the
31 Native Client module returns a message saying ``'hello from NaCl'``. A
32 JavaScript alert panel displays the message received from the Native Client
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. 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_37``. If you don't know which version you need, use the
79 one labeled ``(stable)`` by the ``naclsdk list`` command. See
80 :doc:`Download the Native 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. We recommend that you use a version of
94 Chrome that's the same or newer than the SDK bundle used to build Native Client
95 modules. Older PNaCl modules will always work with newer versions of Chrome, but
96 the converse is not true.
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.
250 #. Start the SDK web server by running ``make server``.
251 #. Re-run the application by reloading ``http://localhost:5103/part1`` in
254 After Chrome loads the Native Client module, you should see the message sent
257 .. _tutorial_troubleshooting:
262 If your application doesn't run, see :ref:`Step 3 <tutorial_step_3>` above to
263 verify that you've set up your environment correctly, including both the Chrome
264 browser and the local server. Make sure that you're running a correct version of
265 Chrome, which is also greater or equal than the SDK bundle version you are
268 Another useful debugging aid is the Chrome JavaScript console (available via the
269 ``Tools`` menu in Chrome). Examine it for clues about what went wrong. For
270 example, if there's a message saying "NaCl module crashed", there is a
271 possibility that the Native Client module has a bug; :doc:`debugging
272 </devguide/devcycle/debugging>` may be required.
274 There's more information about troubleshooting in the documentation:
276 * :ref:`FAQ Troubleshooting <faq_troubleshooting>`.
277 * The :doc:`Progress Events </devguide/coding/progress-events>` document
278 contains some useful information about handling error events.
283 * See the :doc:`Application Structure </devguide/coding/application-structure>`
284 section in the Developer's Guide for information about how to structure a
285 Native Client module.
286 * Check the `C++ Reference </native-client/pepper_stable/cpp>`_ for details
287 about how to use the Pepper APIs.
288 * Browse through the source code of the SDK examples (in the ``examples``
289 directory) to learn additional techniques for writing Native Client
290 applications and using the Pepper APIs.
291 * See the :doc:`Building </devguide/devcycle/building>`, :doc:`Running
292 </devguide/devcycle/running>`, and :doc:`Debugging pages
293 </devguide/devcycle/debugging>` for information about how to build, run, and
294 debug Native Client applications.
295 * Check the `naclports <http://code.google.com/p/naclports/>`_ project to see
296 what libraries have been ported for use with Native Client. If you port an
297 open-source library for your own use, we recommend adding it to naclports
298 (see `How to check code into naclports
299 <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_).