
BUG=None R=laforge@chromium.org,binji@chromium.org,sbc@chromium.org,rockot@chromium.org Review-Url: https://codereview.chromium.org/2875303003 Cr-Commit-Position: refs/heads/master@{#475662}
452 lines
22 KiB
HTML
452 lines
22 KiB
HTML
{{+bindTo:partials.standard_nacl_article}}
|
||
|
||
<b><font color="#cc0000">
|
||
NOTE:
|
||
Deprecation of the technologies described here has been announced
|
||
for platforms other than ChromeOS.<br/>
|
||
Please visit our
|
||
<a href="/native-client/migration">migration guide</a>
|
||
for details.
|
||
</font></b>
|
||
<hr/><section id="c-tutorial-getting-started-part-2">
|
||
<h1 id="c-tutorial-getting-started-part-2">C++ Tutorial: Getting Started (Part 2)</h1>
|
||
<div class="contents local" id="contents" style="display: none">
|
||
<ul class="small-gap">
|
||
<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
|
||
<li><p class="first"><a class="reference internal" href="#using-the-native-client-sdk-build-system" id="id2">Using the Native Client SDK build system</a></p>
|
||
<ul class="small-gap">
|
||
<li><a class="reference internal" href="#simplifying-the-makefile" id="id3">Simplifying the Makefile</a></li>
|
||
<li><a class="reference internal" href="#choosing-valid-toolchains-and-including-common-mk" id="id4">Choosing valid toolchains, and including common.mk</a></li>
|
||
<li><a class="reference internal" href="#configuring-your-project" id="id5">Configuring your project</a></li>
|
||
<li><a class="reference internal" href="#build-macros" id="id6">Build macros</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><p class="first"><a class="reference internal" href="#making-index-html-work-for-chrome-apps" id="id7">Making index.html work for Chrome Apps</a></p>
|
||
<ul class="small-gap">
|
||
<li><a class="reference internal" href="#csp-rules" id="id8">CSP rules</a></li>
|
||
<li><a class="reference internal" href="#making-index-html-csp-compliant" id="id9">Making index.html CSP-compliant</a></li>
|
||
<li><a class="reference internal" href="#making-index-html-support-different-toolchains-and-configurations" id="id10">Making index.html support different toolchains and configurations</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><p class="first"><a class="reference internal" href="#sharing-common-code-with-common-js" id="id11">Sharing common code with common.js</a></p>
|
||
<ul class="small-gap">
|
||
<li><a class="reference internal" href="#loading-the-page-and-creating-the-module" id="id12">Loading the page and creating the module</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#example-specific-behavior-with-example-js" id="id13">Example-specific behavior with example.js</a></li>
|
||
<li><a class="reference internal" href="#compile-the-native-client-module-and-run-the-application-again" id="id14">Compile the Native Client module and run the application again</a></li>
|
||
</ul>
|
||
|
||
</div><h2 id="overview">Overview</h2>
|
||
<p>This tutorial shows how to convert the finished PNaCl web application from
|
||
<a class="reference internal" href="/native-client/devguide/tutorial/tutorial-part1.html"><em>Part 1</em></a> to use the Native Client SDK build system and
|
||
common JavaScript files. It also demonstrates some techniques to make your web
|
||
application <a class="reference external" href="/apps/contentSecurityPolicy">Content Security Policy (CSP)-compliant</a>, which is necessary for <a class="reference external" href="/apps">Chrome Apps</a>.</p>
|
||
<p>Using the Native Client SDK build system makes it easy to build with all of the
|
||
SDK toolchains, and switch between the Debug and Release configurations. It
|
||
also simplifies the makefiles for your project, as we’ll see in the next
|
||
section. Finally, it adds some useful commands for <a class="reference internal" href="/native-client/sdk/examples.html#running-the-sdk-examples"><em>running</em></a> and <a class="reference internal" href="/native-client/sdk/examples.html#debugging-the-sdk-examples"><em>debugging</em></a>
|
||
your application.</p>
|
||
<p>The finished code for this example can be found in the
|
||
<code>pepper_$(VERSION)/getting_started/part2</code> directory in the Native Client SDK
|
||
download.</p>
|
||
<h2 id="using-the-native-client-sdk-build-system">Using the Native Client SDK build system</h2>
|
||
<p>This section describes how to use the SDK build system. To do so, we’ll make
|
||
changes in the makefile. Because the makefile in part1 and part2 are so
|
||
different, it is easier to start from scratch. Here is the contents of the new
|
||
makefile. The following sections will describe it in more detail.</p>
|
||
<h3 id="simplifying-the-makefile">Simplifying the Makefile</h3>
|
||
<p>The makefile from part1 only supports one toolchain (PNaCl) and one
|
||
configuration (Release). It also only supports one source file. It’s relatively
|
||
simple, but if we want to add support for multiple toolchains, configurations,
|
||
source files, or build steps, it would grow increasingly complex. The SDK build
|
||
system uses a set of variables and macros to make this possible, without
|
||
significantly increasing the complexity of the makefile.</p>
|
||
<p>Here is the new makefile, supporting three toolchains (PNaCl, Newlib NaCl,
|
||
Glibc NaCl) and two configurations (Debug, Release).</p>
|
||
<pre class="prettyprint">
|
||
VALID_TOOLCHAINS := pnacl clang-newlib glibc
|
||
|
||
NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
|
||
include $(NACL_SDK_ROOT)/tools/common.mk
|
||
|
||
TARGET = part2
|
||
LIBS = ppapi_cpp ppapi
|
||
|
||
CFLAGS = -Wall
|
||
SOURCES = hello_tutorial.cc
|
||
|
||
# Build rules generated by macros from common.mk:
|
||
|
||
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
|
||
|
||
# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
|
||
# On NaCl, only produce a stripped binary for Release configs (not Debug).
|
||
ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
|
||
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
|
||
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
|
||
else
|
||
$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
|
||
endif
|
||
|
||
$(eval $(call NMF_RULE,$(TARGET),))
|
||
</pre>
|
||
<h3 id="choosing-valid-toolchains-and-including-common-mk">Choosing valid toolchains, and including common.mk</h3>
|
||
<p>The makefile begins by specifying the toolchains that are valid for this
|
||
project. The Native Client SDK build system supports multi-toolchain projects
|
||
for its examples and libraries, but generally you will choose one toolchain
|
||
when you begin your project and never change it. Please see the
|
||
<a class="reference internal" href="/native-client/overview.html#toolchains"><em>Toolchains section of the Native Client overview</em></a> for more
|
||
information.</p>
|
||
<p>For this example, we support the <code>pnacl</code>, <code>clang-newlib</code> and <code>glibc</code>
|
||
toolchains.</p>
|
||
<pre class="prettyprint">
|
||
VALID_TOOLCHAINS := pnacl clang-newlib glibc
|
||
</pre>
|
||
<p>Next, as a convenience, we specify where to find <code>NACL_SDK_ROOT</code>. Because
|
||
this example is located in <code>pepper_$(VERSION)/getting_started/part2</code>, the
|
||
root of the SDK is two directories up.</p>
|
||
<pre class="prettyprint">
|
||
NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
|
||
</pre>
|
||
<aside class="note">
|
||
<blockquote>
|
||
<div>In your own projects, you can use the absolute path to your installed SDK
|
||
here. You can also override this default by setting the <code>NACL_SDK_ROOT</code>
|
||
environment variable. See <a class="reference internal" href="/native-client/devguide/tutorial/tutorial-part1.html#tutorial-step-5"><em>Step 5 of Part 1 of this tutorial</em></a> for more details.</div></blockquote>
|
||
|
||
</aside>
|
||
<p>Next, we include the file <code>tools/common.mk</code>. This file provides the
|
||
functionality for the Native Client SDK build system, including new build rules
|
||
to compile and link a project, which we’ll use below.</p>
|
||
<pre class="prettyprint">
|
||
include $(NACL_SDK_ROOT)/tools/common.mk
|
||
</pre>
|
||
<h3 id="configuring-your-project">Configuring your project</h3>
|
||
<p>After including <code>tools/common.mk</code>, we configure the project by specifying its
|
||
name, the sources and libraries it uses:</p>
|
||
<pre class="prettyprint">
|
||
TARGET = part2
|
||
LIBS = ppapi_cpp ppapi
|
||
|
||
CFLAGS = -Wall
|
||
SOURCES = hello_tutorial.cc
|
||
</pre>
|
||
<p>These variable names are not required and not used by the SDK build system;
|
||
they are only used in the rules described below. By convention, all SDK
|
||
makefiles use the following variables:</p>
|
||
<dl class="docutils">
|
||
<dt>TARGET</dt>
|
||
<dd>The name of the project to build. This variable determines the name of the
|
||
library or executable that will be generated. In the above example, we call
|
||
the target <code>part2</code>, which will generate an executable called
|
||
<code>part2.pexe</code> for PNaCl. For NaCl toolchains, the executable’s file name
|
||
will be given a suffix for its architecture. For example, the ARM executable
|
||
is called <code>part2_arm.nexe</code>.</dd>
|
||
<dt>LIBS</dt>
|
||
<dd>A list of libraries that this executable needs to link against. The library
|
||
search path is already set up to only look in the directory for the current
|
||
toolchain and architecture. In this example, we link against <code>ppapi_cpp</code>
|
||
and <code>ppapi</code>. <code>ppapi_cpp</code> is needed to use the <a class="reference external" href="/native-client/pepper_stable/cpp/">Pepper C++ interface</a>. <code>ppapi</code> is needed for communicating
|
||
with the browser.</dd>
|
||
<dt>CFLAGS</dt>
|
||
<dd>A list of extra flags to pass to the compiler. In this example, we pass
|
||
<code>-Wall</code>, which turns on all warnings.</dd>
|
||
<dt>LDFLAGS</dt>
|
||
<dd>A list of additional flags to pass to the linker. This example does not need
|
||
any special linker flags, so this variable is omitted.</dd>
|
||
<dt>SOURCES</dt>
|
||
<dd>A list of C or C++ sources to compile, separated by spaces. If you have a
|
||
long list of sources, it may be easier to read if you put each file on its
|
||
own line, and use <code>\</code> as a line-continuation character. Here’s an example:</dd>
|
||
</dl>
|
||
<pre class="prettyprint">
|
||
SOURCES = foo.cc \
|
||
bar.cc \
|
||
baz.cc \
|
||
quux.cc
|
||
</pre>
|
||
<h3 id="build-macros">Build macros</h3>
|
||
<p>For many projects, the following build macros do not need to be changed; they
|
||
will use the variables we’ve defined above.</p>
|
||
<pre class="prettyprint">
|
||
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
|
||
|
||
ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
|
||
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
|
||
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
|
||
else
|
||
$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
|
||
endif
|
||
|
||
$(eval $(call NMF_RULE,$(TARGET),))
|
||
</pre>
|
||
<p>The first line defines rules to compile each source in <code>SOURCES</code>, using the
|
||
flags in <code>CFLAGS</code>:</p>
|
||
<pre class="prettyprint">
|
||
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
|
||
</pre>
|
||
<p>The next six lines define rules to link the object files into one or more
|
||
executables. When <code>TOOLCHAIN</code> is <code>pnacl</code>, there is only one executable
|
||
generated: in the example above, <code>part2.pexe</code>. When using a NaCl toolchain,
|
||
there will be three executables generated, one for each architecture: in the
|
||
example above, <code>part2_arm.nexe</code>, <code>part2_x86_32.nexe</code> and
|
||
<code>part2_x86_64.nexe</code>.</p>
|
||
<p>When <code>CONFIG</code> is <code>Release</code>, each executable is also stripped to remove
|
||
debug information and reduce the file size. Otherwise, when the <code>TOOLCHAIN</code>
|
||
is <code>pnacl</code>, the workflow involves creating an unstripped binary for debugging
|
||
and then finalizing it and stripping it for publishing.</p>
|
||
<pre class="prettyprint">
|
||
ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
|
||
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
|
||
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
|
||
else
|
||
$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
|
||
endif
|
||
</pre>
|
||
<p>Finally, the NMF rule generates a NaCl manifest file (<code>.nmf</code>) that references
|
||
each executable generated in the previous step:</p>
|
||
<pre class="prettyprint">
|
||
$(eval $(call NMF_RULE,$(TARGET),))
|
||
</pre>
|
||
<h2 id="making-index-html-work-for-chrome-apps">Making index.html work for Chrome Apps</h2>
|
||
<p>This section describes the changes necessary to make the HTML and JavaScript in
|
||
part1 CSP-compliant. This is required if you want to build a <a class="reference external" href="/apps">Chrome App</a>, but is not necessary if you want to use PNaCl on the open web.</p>
|
||
<h3 id="csp-rules">CSP rules</h3>
|
||
<p><a class="reference external" href="/apps/contentSecurityPolicy#what">Chrome Apps CSP</a> restricts you from doing
|
||
the following:</p>
|
||
<ul class="small-gap">
|
||
<li>You can’t use inline scripting in your Chrome App pages. The restriction
|
||
bans both <code><script></code> blocks and event handlers (<code><button onclick="..."></code>).</li>
|
||
<li>You can’t reference any external resources in any of your app files (except
|
||
for video and audio resources). You can’t embed external resources in an
|
||
iframe.</li>
|
||
<li>You can’t use string-to-JavaScript methods like <code>eval()</code> and <code>new
|
||
Function()</code>.</li>
|
||
</ul>
|
||
<h3 id="making-index-html-csp-compliant">Making index.html CSP-compliant</h3>
|
||
<p>To make our application CSP-compliant, we have to remove inline scripting. As
|
||
described above, we can’t use inline <code><script></code> blocks or event handlers. This
|
||
is easy to do—we’ll just reference some new files from our script tag, and
|
||
remove all of our inlined scripts:</p>
|
||
<pre class="prettyprint">
|
||
<head>
|
||
...
|
||
<script type="text/javascript" src="common.js"></script>
|
||
<script type="text/javascript" src="example.js"></script>
|
||
</head>
|
||
</pre>
|
||
<p><code>common.js</code> has shared code used by all SDK examples, and is described
|
||
later in this document. <code>example.js</code> is a script that has code specific to
|
||
this example.</p>
|
||
<p>We also need to remove the inline event handler on the body tag:</p>
|
||
<pre class="prettyprint">
|
||
<body onload="pageDidLoad()">
|
||
...
|
||
</pre>
|
||
<p>This logic is now handled by <code>common.js</code>.</p>
|
||
<h3 id="making-index-html-support-different-toolchains-and-configurations">Making index.html support different toolchains and configurations</h3>
|
||
<p>Finally, there are a few changes to <code>index.html</code> that are not necessary for
|
||
CSP-compliance, but help make the SDK examples more generic.</p>
|
||
<p>First, we add some <a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes">data attributes</a>
|
||
to the body element to specify the name, supported toolchains, supported
|
||
configurations, and path to the <code>.nmf</code> file:</p>
|
||
<pre class="prettyprint">
|
||
<body data-name="part2"
|
||
data-tools="clang-newlib glibc pnacl"
|
||
data-configs="Debug Release"
|
||
data-path="{tc}/{config}">
|
||
...
|
||
</pre>
|
||
<p><code>common.js</code> will read these data attributes to allow you to load the same
|
||
example with different toolchains by changing the URL’s <a class="reference external" href="http://en.wikipedia.org/wiki/Query_string">query string</a>. For example, you can load the
|
||
glibc Debug version of this example by navigating to
|
||
<code>index.html?tc=glibc&config=Debug</code>. Path URI’s such as <code>../</code>, for example
|
||
do not work for either the data-path parameter or its corresponding query
|
||
string.</p>
|
||
<p>Next, we remove the <code>embed</code> element that is described in HTML. This will be
|
||
automatically added for us by <code>common.js</code>, based on the current
|
||
toolchain/configuration combination:</p>
|
||
<pre class="prettyprint">
|
||
<!--
|
||
Just as in part1, the <embed> element will be wrapped inside the <div>
|
||
element with the id "listener". In part1, the embed was specified in HTML,
|
||
here the common.js module creates a new <embed> element and adds it to the
|
||
<div> for us.
|
||
-->
|
||
<div id="listener"></div>
|
||
</pre>
|
||
<h2 id="sharing-common-code-with-common-js">Sharing common code with common.js</h2>
|
||
<p><code>common.js</code> contains JavaScript code that each example uses to create a
|
||
NaCl module, handle messages from that module and other common tasks like
|
||
displaying the module load status and logging messages. Explaining all of
|
||
<code>common.js</code> is outside the scope of this document, but please look at the
|
||
documentation in that file for more information.</p>
|
||
<h3 id="loading-the-page-and-creating-the-module">Loading the page and creating the module</h3>
|
||
<p>Since we’ve added <code><script></code> tags for <code>common.js</code> and <code>example.js</code> to the
|
||
<code>head</code> element, they will be loaded and executed before the rest of the
|
||
document has been parsed. As a result, we have to wait for the page to finish
|
||
loading before we try to create the embed element and add it to the page.</p>
|
||
<p>We can do that by calling <code>addEventListener</code> and listening for the
|
||
<code>DOMContentLoaded</code> event:</p>
|
||
<pre class="prettyprint">
|
||
// Listen for the DOM content to be loaded. This event is fired when parsing of
|
||
// the page's document has finished.
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
...
|
||
});
|
||
</pre>
|
||
<p>Inside this function, we parse the URL query string, and compare that to the
|
||
data attributes:</p>
|
||
<pre class="prettyprint">
|
||
// From https://developer.mozilla.org/en-US/docs/DOM/window.location
|
||
var searchVars = {};
|
||
if (window.location.search.length > 1) {
|
||
var pairs = window.location.search.substr(1).split('&');
|
||
for (var key_ix = 0; key_ix < pairs.length; key_ix++) {
|
||
var keyValue = pairs[key_ix].split('=');
|
||
searchVars[unescape(keyValue[0])] =
|
||
keyValue.length > 1 ? unescape(keyValue[1]) : '';
|
||
}
|
||
}
|
||
|
||
...
|
||
|
||
var toolchains = body.dataset.tools.split(' ');
|
||
var configs = body.dataset.configs.split(' ');
|
||
|
||
...
|
||
|
||
var tc = toolchains.indexOf(searchVars.tc) !== -1 ?
|
||
searchVars.tc : toolchains[0];
|
||
|
||
// If the config value is included in the search vars, use that.
|
||
// Otherwise default to Release if it is valid, or the first value if
|
||
// Release is not valid.
|
||
if (configs.indexOf(searchVars.config) !== -1)
|
||
var config = searchVars.config;
|
||
else if (configs.indexOf('Release') !== -1)
|
||
var config = 'Release';
|
||
else
|
||
var config = configs[0];
|
||
</pre>
|
||
<p>Then <code>domContentLoaded</code> is called, which performs some checks to see if the
|
||
browser supports Native Client, then creates the NaCl module.</p>
|
||
<pre class="prettyprint">
|
||
function domContentLoaded(name, tool, path, width, height, attrs) {
|
||
updateStatus('Page loaded.');
|
||
if (!browserSupportsNaCl(tool)) {
|
||
updateStatus(
|
||
'Browser does not support NaCl (' + tool + '), or NaCl is disabled');
|
||
} else if (common.naclModule == null) {
|
||
updateStatus('Creating embed: ' + tool);
|
||
|
||
// We use a non-zero sized embed to give Chrome space to place the bad
|
||
// plug-in graphic, if there is a problem.
|
||
width = typeof width !== 'undefined' ? width : 200;
|
||
height = typeof height !== 'undefined' ? height : 200;
|
||
attachDefaultListeners();
|
||
createNaClModule(name, tool, path, width, height, attrs);
|
||
} else {
|
||
// It's possible that the Native Client module onload event fired
|
||
// before the page's onload event. In this case, the status message
|
||
// will reflect 'SUCCESS', but won't be displayed. This call will
|
||
// display the current message.
|
||
updateStatus('Waiting.');
|
||
}
|
||
}
|
||
</pre>
|
||
<p><code>attachDefaultListeners</code> is added before the creation of the module, to make
|
||
sure that no messages are lost. Note that <code>window.attachListeners</code> is also
|
||
called; this is the way that <code>common.js</code> allows each example to configure
|
||
itself differently. If an example defines the <code>attachListeners</code> function, it
|
||
will be called by <code>common.js</code>.</p>
|
||
<pre class="prettyprint">
|
||
function attachDefaultListeners() {
|
||
var listenerDiv = document.getElementById('listener');
|
||
listenerDiv.addEventListener('load', moduleDidLoad, true);
|
||
listenerDiv.addEventListener('message', handleMessage, true);
|
||
listenerDiv.addEventListener('crash', handleCrash, true);
|
||
if (typeof window.attachListeners !== 'undefined') {
|
||
window.attachListeners();
|
||
}
|
||
}
|
||
</pre>
|
||
<p>Finally, <code>createNaClModule</code> actually creates the <code>embed</code>, and appends it as
|
||
a child of the element with id <code>listener</code>:</p>
|
||
<pre class="prettyprint">
|
||
function createNaClModule(name, tool, path, width, height, attrs) {
|
||
var moduleEl = document.createElement('embed');
|
||
moduleEl.setAttribute('name', 'nacl_module');
|
||
moduleEl.setAttribute('id', 'nacl_module');
|
||
moduleEl.setAttribute('width', width);
|
||
moduleEl.setAttribute('height', height);
|
||
moduleEl.setAttribute('path', path);
|
||
moduleEl.setAttribute('src', path + '/' + name + '.nmf');
|
||
|
||
...
|
||
|
||
var mimetype = mimeTypeForTool(tool);
|
||
moduleEl.setAttribute('type', mimetype);
|
||
|
||
var listenerDiv = document.getElementById('listener');
|
||
listenerDiv.appendChild(moduleEl);
|
||
...
|
||
}
|
||
</pre>
|
||
<p>When the module finishes loading, it will dispatch a <code>load</code> event, and the
|
||
event listener function that was registered above (<code>moduleDidLoad</code>) will be
|
||
called. Note that <code>common.js</code> allows each example to define a
|
||
<code>window.moduleDidLoad</code> function, that will be called here as well.</p>
|
||
<pre class="prettyprint">
|
||
function moduleDidLoad() {
|
||
common.naclModule = document.getElementById('nacl_module');
|
||
updateStatus('RUNNING');
|
||
|
||
if (typeof window.moduleDidLoad !== 'undefined') {
|
||
window.moduleDidLoad();
|
||
}
|
||
}
|
||
</pre>
|
||
<h2 id="example-specific-behavior-with-example-js">Example-specific behavior with example.js</h2>
|
||
<p>As described in the previous section, <code>common.js</code> will call certain functions
|
||
during the module loading process. This example only needs to respond to two:
|
||
<code>moduleDidLoad</code> and <code>handleMessage</code>.</p>
|
||
<pre class="prettyprint">
|
||
// This function is called by common.js when the NaCl module is
|
||
// loaded.
|
||
function moduleDidLoad() {
|
||
// Once we load, hide the plugin. In this example, we don't display anything
|
||
// in the plugin, so it is fine to hide it.
|
||
common.hideModule();
|
||
|
||
// After the NaCl module has loaded, common.naclModule is a reference to the
|
||
// NaCl module's <embed> element.
|
||
//
|
||
// postMessage sends a message to it.
|
||
common.naclModule.postMessage('hello');
|
||
}
|
||
|
||
// This function is called by common.js when a message is received from the
|
||
// NaCl module.
|
||
function handleMessage(message) {
|
||
var logEl = document.getElementById('log');
|
||
logEl.textContent += message.data;
|
||
}
|
||
</pre>
|
||
<h2 id="compile-the-native-client-module-and-run-the-application-again">Compile the Native Client module and run the application again</h2>
|
||
<ol class="arabic">
|
||
<li><p class="first">Compile the Native Client module by running the <code>make</code> command again.</p>
|
||
</li>
|
||
<li><p class="first">Start the SDK web server by running <code>make server</code>.</p>
|
||
</li>
|
||
<li><p class="first">Re-run the application by reloading <code>http://localhost:5103/part2</code> in
|
||
Chrome.</p>
|
||
<p>After Chrome loads the Native Client module, you should see the message sent
|
||
from the module.</p>
|
||
</li>
|
||
</ol>
|
||
</section>
|
||
|
||
{{/partials.standard_nacl_article}}
|