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