tutorial-part1.html revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1{{+bindTo:partials.standard_nacl_article}} 2 3<section id="c-tutorial-getting-started-part-1"> 4<span id="tutorial"></span><h1 id="c-tutorial-getting-started-part-1"><span id="tutorial"></span>C++ Tutorial: Getting Started (Part 1)</h1> 5<div class="contents local" id="contents" style="display: none"> 6<ul class="small-gap"> 7<li><p class="first"><a class="reference internal" href="#overview" id="id1">Overview</a></p> 8<ul class="small-gap"> 9<li><a class="reference internal" href="#what-the-application-in-this-tutorial-does" id="id2">What the application in this tutorial does</a></li> 10<li><a class="reference internal" href="#communication-between-javascript-and-native-client-modules" id="id3">Communication between JavaScript and Native Client modules</a></li> 11</ul> 12</li> 13<li><a class="reference internal" href="#step-1-download-and-install-the-native-client-sdk" id="id4">Step 1: Download and install the Native Client SDK</a></li> 14<li><a class="reference internal" href="#step-2-start-a-local-server" id="id5">Step 2: Start a local server</a></li> 15<li><a class="reference internal" href="#step-3-set-up-the-chrome-browser" id="id6">Step 3: Set up the Chrome browser</a></li> 16<li><a class="reference internal" href="#step-4-stub-code-for-the-tutorial" id="id7">Step 4: Stub code for the tutorial</a></li> 17<li><a class="reference internal" href="#step-5-compile-the-native-client-module-and-run-the-stub-application" id="id8">Step 5: Compile the Native Client module and run the stub application</a></li> 18<li><a class="reference internal" href="#step-6-modify-the-javascript-code-to-send-a-message-to-the-native-client-module" id="id9">Step 6: Modify the JavaScript code to send a message to the Native Client module</a></li> 19<li><a class="reference internal" href="#step-7-implement-a-message-handler-in-the-native-client-module" id="id10">Step 7: Implement a message handler in the Native Client module</a></li> 20<li><a class="reference internal" href="#step-8-compile-the-native-client-module-and-run-the-application-again" id="id11">Step 8: Compile the Native Client module and run the application again</a></li> 21<li><a class="reference internal" href="#troubleshooting" id="id12">Troubleshooting</a></li> 22<li><a class="reference internal" href="#next-steps" id="id13">Next steps</a></li> 23</ul> 24 25</div><h2 id="overview">Overview</h2> 26<p>This tutorial shows how to build and run a web application using Portable Native 27Client (PNaCl). This is a client-side application that uses HTML, JavaScript and 28a Native Client module written in C++. The PNaCl toolchain is used to enable 29running the Native Client module directly from a web page.</p> 30<p>It’s recommended to read the <a class="reference internal" href="/native-client/overview.html"><em>Native Client Technical Overview</em></a> prior to going through this tutorial.</p> 31<h3 id="what-the-application-in-this-tutorial-does">What the application in this tutorial does</h3> 32<p>The application in this tutorial shows how to load a Native Client module in a 33web page, and how to send messages between JavaScript and the C++ code in the 34Native Client module. In this simple application, the JavaScript code in the web 35page sends a <code>'hello'</code> message to the Native Client module. When the Native 36Client module receives a message, it checks whether the message is equal to the 37string <code>'hello'</code>. If it is, the Native Client module returns a message saying 38<code>'hello from NaCl'</code>. A JavaScript alert panel displays the message received 39from the Native Client module.</p> 40<h3 id="communication-between-javascript-and-native-client-modules">Communication between JavaScript and Native Client modules</h3> 41<p>The Native Client programming model supports bidirectional communication between 42JavaScript and the Native Client module (C/C++ code). Both sides can initiate 43and respond to messages. In all cases, the communication is asynchronous: The 44caller (JavaScript or the Native Client module) sends a message, but the caller 45does not wait for, or may not even expect, a response. This behavior is 46analogous to client/server communication on the web, where the client posts a 47message to the server and returns immediately. The Native Client messaging 48system is part of the Pepper API, and is described in detail in 49<a class="reference internal" href="/native-client/devguide/coding/message-system.html"><em>Developer’s Guide: Messaging System</em></a>. 50It is also similar to the way <a class="reference external" href="http://en.wikipedia.org/wiki/Web_worker">web workers</a> interact with the main document in 51JavaScript.</p> 52<h2 id="step-1-download-and-install-the-native-client-sdk">Step 1: Download and install the Native Client SDK</h2> 53<p>Follow the instructions on the <a class="reference internal" href="/native-client/sdk/download.html"><em>Download</em></a> page to 54download and install the Native Client SDK.</p> 55<h2 id="step-2-start-a-local-server"><span id="tutorial-step-2"></span>Step 2: Start a local server</h2> 56<p>To simulate a production environment, the SDK provides a simple web server that 57can be used to serve the application on <code>localhost</code>. A convenience Makefile 58rule called <code>serve</code> is the easiest way to invoke it:</p> 59<pre> 60$ cd pepper_$(VERSION)/getting_started 61$ make serve 62</pre> 63<aside class="note"> 64The SDK may consist of several “bundles”, one per Chrome/Pepper version (see 65<a class="reference internal" href="/native-client/version.html"><em>versioning information</em></a>). In the sample invocation above 66<code>pepper_$(VERSION)</code> refers to the specific version you want to use. For 67example, <code>pepper_31</code>. If you don’t know which version you need, use the 68one labeled <code>(stable)</code> by <code>naclsdk list</code>. See <a class="reference internal" href="/native-client/sdk/download.html"><em>Download the Native 69Client SDK</em></a> for more details. 70</aside> 71<p>If no port number is specified, the server defaults to port 5103, and can be 72accessed at <code>http://localhost:5103</code>.</p> 73<p>Any server can be used for the purpose of development. The one provided with the 74SDK is just a convenience, not a requirement.</p> 75<h2 id="step-3-set-up-the-chrome-browser"><span id="tutorial-step-3"></span>Step 3: Set up the Chrome browser</h2> 76<p>PNaCl is enabled by default in Chrome version 31 and later. Please make sure 77that you have a suitable version to work through this tutorial. It’s also 78important to use a Chrome version that’s the same or newer than the SDK bundle 79used to build the Native Client modules.</p> 80<aside class="note"> 81To find out the version of Chrome, type <code>about:chrome</code> in the address bar. 82</aside> 83<p>For a better development experience, it’s also recommended to disable the 84Chrome cache. Chrome caches resources aggressively; disabling the cache helps 85make sure that the latest version of the Native Client module is loaded during 86development.</p> 87<ul class="small-gap"> 88<li>Open Chrome’s developer tools by clicking the menu icon <img alt="menu-icon" src="/native-client/images/menu-icon.png" /> and 89choosing <code>Tools > Developer tools</code>.</li> 90<li>Click the gear icon <img alt="gear-icon" src="/native-client/images/gear-icon.png" /> in the bottom right corner of the Chrome 91window.</li> 92<li>Under the “General” settings, check the box next to “Disable cache (while 93DevTools is open)”.</li> 94<li>Keep the Developer Tools pane open while developing Native Client 95applications.</li> 96</ul> 97<h2 id="step-4-stub-code-for-the-tutorial">Step 4: Stub code for the tutorial</h2> 98<p>The stub code for the tutorial is avalable in the SDK, in 99<code>pepper_$(VERSION)/getting_started/part1</code>. It contains the following files:</p> 100<ul class="small-gap"> 101<li><p class="first"><code>index.html</code>: Contains the HTML layout of the page as well as the JavaScript 102code that interacts with the Native Client module.</p> 103<p>The Native Client module is included in the page with an <code><embed></code> tag that 104points to a manifest file.</p> 105</li> 106<li><code>hello_tutorial.nmf</code>: A manifest file that’s used to point the HTML to the 107Native Client module and optionally provide additional commands to the PNaCl 108translator that is part of the Chrome browser.</li> 109<li><code>hello_tutorial.cc</code>: C++ code for a simple Native Client module.</li> 110<li><code>Makefile</code>: Compilation commands to build the <strong>pexe</strong> (portable executable) 111from the C++ code in <code>hello_tutorial.cc</code>.</li> 112</ul> 113<p>It’s a good idea to take a look at these files now—they contain a large amount 114of comments that help explain their structure and contents. For more details 115on the structure of a typical Native Client application, see 116<a class="reference internal" href="/native-client/devguide/coding/application-structure.html"><em>Application Structure</em></a>.</p> 117<p>The stub code is intentionally very minimal. The C++ code does not do anything 118except correctly initialize itself. The JavaScript code waits for the Native 119Client module to load and changes the status text on the web page accordingly.</p> 120<h2 id="step-5-compile-the-native-client-module-and-run-the-stub-application"><span id="tutorial-step-5"></span>Step 5: Compile the Native Client module and run the stub application</h2> 121<p>To compile the Native Client module, run <code>make</code>:</p> 122<pre> 123$ cd pepper_$(VERSION)/getting_started/part1 124$ make 125</pre> 126<p>Since the sample is located within the SDK tree, the Makefile knows how to find 127the PNaCl toolchain automatically and use it to build the module. If you’re 128building applications outside the NaCl SDK tree, you should set the 129<code>$NACL_SDK_ROOT</code> environment variable. See <a class="reference internal" href="/native-client/devguide/devcycle/building.html"><em>Building Native Client 130Modules</em></a> for more details.</p> 131<p>Assuming the local server was started according to the instructions in 132<a class="reference internal" href="#tutorial-step-2"><em>Step 2</em></a>, you can now load the sample by pointing Chrome 133to <code>http://localhost:5103/part1</code>. Chrome should load the Native Client module 134successfully and the Status text should change from “LOADING...” to “SUCCESS”. 135If you run into problems, check out the <a class="reference internal" href="#tutorial-troubleshooting"><em>Troubleshooting section</em></a> below.</p> 136<h2 id="step-6-modify-the-javascript-code-to-send-a-message-to-the-native-client-module">Step 6: Modify the JavaScript code to send a message to the Native Client module</h2> 137<p>In this step, you’ll modify the web page (<code>index.html</code>) to send a message to 138the Native Client module after the page loads the module.</p> 139<p>Look for the JavaScript function <code>moduleDidLoad()</code>, and add new code to send 140a ‘hello’ message to the module. The new function should look as follows:</p> 141<pre class="prettyprint"> 142function moduleDidLoad() { 143 HelloTutorialModule = document.getElementById('hello_tutorial'); 144 updateStatus('SUCCESS'); 145 // Send a message to the Native Client module 146 HelloTutorialModule.postMessage('hello'); 147} 148</pre> 149<h2 id="step-7-implement-a-message-handler-in-the-native-client-module">Step 7: Implement a message handler in the Native Client module</h2> 150<p>In this step, you’ll modify the Native Client module (<code>hello_tutorial.cc</code>) to 151respond to the message received from the JavaScript code in the application. 152Specifically, you’ll:</p> 153<ul class="small-gap"> 154<li>Implement the <code>HandleMessage()</code> member function of the module instance.</li> 155<li>Use the <code>PostMessage()</code> member function to send a message from the module to 156the JavaScript code.</li> 157</ul> 158<p>First, add code to define the variables used by the Native Client module (the 159‘hello’ string you’re expecting to receive from JavaScript and the reply string 160you want to return to JavaScript as a response). In the file 161<code>hello_tutorial.cc</code>, add this code after the <code>#include</code> statements:</p> 162<pre class="prettyprint"> 163namespace { 164// The expected string sent by the browser. 165const char* const kHelloString = "hello"; 166// The string sent back to the browser upon receipt of a message 167// containing "hello". 168const char* const kReplyString = "hello from NaCl"; 169} // namespace 170</pre> 171<p>Now, implement the <code>HandleMessage()</code> member function to check for 172<code>kHelloString</code> and return <code>kReplyString.</code> Look for the following line:</p> 173<pre class="prettyprint"> 174// TODO(sdk_user): 1. Make this function handle the incoming message. 175</pre> 176<p>Populate the member function with code, as follows:</p> 177<pre class="prettyprint"> 178virtual void HandleMessage(const pp::Var& var_message) { 179 if (!var_message.is_string()) 180 return; 181 std::string message = var_message.AsString(); 182 pp::Var var_reply; 183 if (message == kHelloString) { 184 var_reply = pp::Var(kReplyString); 185 PostMessage(var_reply); 186 } 187} 188</pre> 189<p>See the Pepper API documentation for additional information about the 190<a class="reference external" href="/native-client/pepper_stable/cpp/classpp_1_1_instance.html#a5dce8c8b36b1df7cfcc12e42397a35e8">pp::Instance.HandleMessage</a> 191and <a class="reference external" href="/native-client/pepper_stable/cpp/classpp_1_1_instance.html#a67e888a4e4e23effe7a09625e73ecae9">pp::Instance.PostMessage</a> 192member functions.</p> 193<h2 id="step-8-compile-the-native-client-module-and-run-the-application-again">Step 8: Compile the Native Client module and run the application again</h2> 194<p>Compile the Native Client module by running the <code>make</code> command again.</p> 195<p>Re-run the application by reloading <code>http://localhost:5103/part1</code> in Chrome.</p> 196<p>After Chrome loads the Native Client module, you should see an alert panel 197appear with the message sent from the module.</p> 198<h2 id="troubleshooting"><span id="tutorial-troubleshooting"></span>Troubleshooting</h2> 199<p>If your application doesn’t run, see <a class="reference internal" href="#tutorial-step-3"><em>Step 3</em></a> above to 200verify that you’ve set up your environment correctly, including both the Chrome 201browser and the local server. Make sure that you’re running a correct version of 202Chrome, which is also greater or equal than the SDK bundle version you are 203using.</p> 204<p>Another useful debugging aid is the Chrome JavaScript console (available via the 205<code>Tools</code> menu in Chrome). Examine it for clues about what went wrong. For 206example, if there’s a message saying “NaCl module crashed”, there is a 207possibility that the Native Client module has a bug; <a class="reference internal" href="/native-client/devguide/devcycle/debugging.html"><em>debugging</em></a> may be required.</p> 208<p>There’s more information about troubleshooting in the documentation:</p> 209<ul class="small-gap"> 210<li><a class="reference internal" href="/native-client/faq.html#faq-troubleshooting"><em>FAQ Troubleshooting</em></a>.</li> 211<li>The <a class="reference internal" href="/native-client/devguide/coding/progress-events.html"><em>Progress Events</em></a> document 212contains some useful information about handling error events.</li> 213</ul> 214<h2 id="next-steps">Next steps</h2> 215<ul class="small-gap"> 216<li>See the <a class="reference internal" href="/native-client/devguide/coding/application-structure.html"><em>Application Structure</em></a> 217chapter in the Developer’s Guide for information about how to structure a 218Native Client module.</li> 219<li>Check the <a class="reference external" href="/native-client/pepper_stable/cpp">C++ Reference</a> for details 220about how to use the Pepper APIs.</li> 221<li>Browse through the source code of the SDK examples (in the <code>examples</code> 222directory) to learn additional techniques for writing Native Client 223applications and using the Pepper APIs.</li> 224<li>See the <a class="reference internal" href="/native-client/devguide/devcycle/building.html"><em>Building</em></a>, <a class="reference internal" href="/native-client/devguide/devcycle/running.html"><em>Running</em></a>, and <a class="reference internal" href="/native-client/devguide/devcycle/debugging.html"><em>Debugging pages</em></a> for information about how to build, run, and 225debug Native Client applications.</li> 226<li>Check the <a class="reference external" href="http://code.google.com/p/naclports/">naclports</a> project to see 227what libraries have been ported for use with Native Client. If you port an 228open-source library for your own use, we recommend adding it to naclports 229(see <a class="reference external" href="http://code.google.com/p/naclports/wiki/HowTo_Checkin">How to check code into naclports</a>).</li> 230</ul> 231</section> 232 233{{/partials.standard_nacl_article}} 234