Home | History | Annotate | Download | only in coding
      1 {{+bindTo:partials.standard_nacl_article}}
      2 
      3 <section id="native-client-modules">
      4 <span id="devcycle-native-client-modules"></span><h1 id="native-client-modules"><span id="devcycle-native-client-modules"></span>Native Client Modules</h1>
      5 <p>This document describes the classes and functions that you need to implement in
      6 a Native Client module in order for Chrome to load, initialize, and run it.  The
      7 requirements are the same regardless of whether or not the module uses PNaCl,
      8 but depend on whether the module is written in C or C++.</p>
      9 <div class="contents local" id="contents" style="display: none">
     10 <ul class="small-gap">
     11 <li><a class="reference internal" href="#introduction" id="id2">Introduction</a></li>
     12 <li><a class="reference internal" href="#writing-modules-in-c" id="id3">Writing modules in C</a></li>
     13 <li><a class="reference internal" href="#id1" id="id4">Writing modules in C++</a></li>
     14 </ul>
     15 
     16 </div><section id="introduction">
     17 <h2 id="introduction">Introduction</h2>
     18 <p>Native Client modules do not have a <code>main()</code> function. When a module loads,
     19 the Native Client runtime calls the code in the module to create an instance and
     20 initialize the interfaces for the APIs the module uses. This initialization
     21 sequence depends on whether the module is written in C or C++ and requires that
     22 you implement specific functions in each case.</p>
     23 </section><section id="writing-modules-in-c">
     24 <h2 id="writing-modules-in-c">Writing modules in C</h2>
     25 <p>The C API uses a prefix convention to show whether an interface is implemented
     26 in the browser or in a module. Interfaces starting with <code>PPB_</code> (which can be
     27 read as &#8220;Pepper <em>browser</em>&#8221;) are implemented in the browser and they are called
     28 from your module. Interfaces starting with <code>PPP_</code> (&#8220;Pepper <em>plugin</em>&#8221;) are
     29 implemented in the module; they are called from the browser and will execute on
     30 the main thread of the module instance.</p>
     31 <p>When you implement a Native Client module in C you must include these components:</p>
     32 <ul class="small-gap">
     33 <li>The functions <code>PPP_InitializeModule</code> and <code>PPP_GetInterface</code></li>
     34 <li>Code that implements the interface <code>PPP_Instance</code> and any other C interfaces
     35 that your module uses</li>
     36 </ul>
     37 <p>For each PPP interface, you must implement all of its functions, create the
     38 struct through which the browser calls the interface, and insure that the
     39 function <code>PPP_GetInterface</code> returns the appropriate struct for the interface.</p>
     40 <p>For each PPB interface, you must declare a pointer to the interface and
     41 initialize the pointer with a call to <code>get_browser</code> inside
     42 <code>PPP_InitializeModule</code>.</p>
     43 <p>These steps are illustrated in the code excerpt below, which shows the
     44 implementation and initialization of the required <code>PPP_Instance</code>
     45 interface. The code excerpt also shows the initialization of three additional
     46 interfaces which are not required: <code>PPB_Instance</code> (through which the Native
     47 Client module calls back to the browser) and <code>PPB_InputEvent</code> and
     48 <code>PPP_InputEvent</code>.</p>
     49 <pre class="prettyprint">
     50 #include &lt;stdlib.h&gt;
     51 #include &lt;string.h&gt;
     52 #include &quot;ppapi/c/pp_errors.h&quot;
     53 #include &quot;ppapi/c/ppp.h&quot;
     54 // Include the interface headers.
     55 // PPB APIs describe calls from the module to the browser.
     56 // PPP APIs describe calls from the browser to the functions defined in your module.
     57 #include &quot;ppapi/c/ppb_instance.h&quot;
     58 #include &quot;ppapi/c/ppp_instance.h&quot;
     59 #include &quot;ppapi/c/ppb_input_event.h&quot;
     60 #include &quot;ppapi/c/ppp_input_event.h&quot;
     61 
     62 // Create pointers for each PPB interface that your module uses.
     63 static PPB_Instance* ppb_instance_interface = NULL;
     64 static PPB_InputEvent* ppb_input_event_interface = NULL;
     65 
     66 // Define all the functions for each PPP interface that your module uses.
     67 // Here is a stub for the first function in PPP_Instance.
     68 static PP_Bool Instance_DidCreate(PP_Instance instance,
     69                                   uint32_t argc,
     70                                   const char* argn[],
     71                                   const char* argv[]) {
     72         return PP_TRUE;
     73 }
     74 // ... more API functions ...
     75 
     76 // Define PPP_GetInterface.
     77 // This function should return a non-NULL value for every interface you are using.
     78 // The string for the name of the interface is defined in the interface's header file.
     79 // The browser calls this function to get pointers to the interfaces that your module implements.
     80 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
     81         // Create structs for each PPP interface.
     82         // Assign the interface functions to the data fields.
     83          if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
     84                 static PPP_Instance instance_interface = {
     85                         &amp;Instance_DidCreate,
     86                         // The definitions of these functions are not shown
     87                         &amp;Instance_DidDestroy,
     88                         &amp;Instance_DidChangeView,
     89                         &amp;Instance_DidChangeFocus,
     90                         &amp;Instance_HandleDocumentLoad
     91                 };
     92                 return &amp;instance_interface;
     93          }
     94 
     95          if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0) {
     96                 static PPP_InputEvent input_interface = {
     97                         // The definition of this function is not shown.
     98                         &amp;Instance_HandleInput,
     99                 };
    100                 return &amp;input_interface;
    101          }
    102          // Return NULL for interfaces that you do not implement.
    103          return NULL;
    104 }
    105 
    106 // Define PPP_InitializeModule, the entry point of your module.
    107 // Retrieve the API for the browser-side (PPB) interfaces you will use.
    108 PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) {
    109         ppb_instance_interface = (PPB_Instance*)(get_browser(PPB_INSTANCE_INTERFACE));
    110         ppb_input_event_interface = (PPB_InputEvent*)(get_browser(PPB_INPUT_EVENT_INTERFACE));
    111         return PP_OK;
    112 }
    113 </pre>
    114 </section><section id="id1">
    115 <h2 id="id1">Writing modules in C++</h2>
    116 <p>When you implement a Native Client module in C++ you must include these components:</p>
    117 <ul class="small-gap">
    118 <li>The factory function called <code>CreateModule()</code></li>
    119 <li>Code that defines your own Module class (derived from the <code>pp::Module</code>
    120 class)</li>
    121 <li>Code that defines your own Instance class (derived from the <code>pp:Instance</code>
    122 class)</li>
    123 </ul>
    124 <p>In the &#8220;Hello tutorial&#8221; example (in the <code>getting_started/part1</code> directory of
    125 the NaCl SDK), these three components are specified in the file
    126 <code>hello_tutorial.cc</code>. Here is the factory function:</p>
    127 <pre class="prettyprint">
    128 namespace pp {
    129 Module* CreateModule() {
    130   return new HelloTutorialModule();
    131 }
    132 }
    133 </pre>
    134 <p>The <code>CreateModule()</code> factory function is the main binding point between a
    135 module and the browser, and serves as the entry point into the module. The
    136 browser calls <code>CreateModule()</code> when a module is first loaded; this function
    137 returns a Module object derived from the <code>pp::Module</code> class. The browser keeps
    138 a singleton of the Module object.</p>
    139 <p>Below is the Module class from the &#8220;Hello tutorial&#8221; example:</p>
    140 <pre class="prettyprint">
    141 class HelloTutorialModule : public pp::Module {
    142  public:
    143   HelloTutorialModule() : pp::Module() {}
    144   virtual ~HelloTutorialModule() {}
    145 
    146   virtual pp::Instance* CreateInstance(PP_Instance instance) {
    147     return new HelloTutorialInstance(instance);
    148   }
    149 };
    150 </pre>
    151 <p>The Module class must include a <code>CreateInstance()</code> method. The browser calls
    152 the <code>CreateInstance()</code> method every time it encounters an <code>&lt;embed&gt;</code> element
    153 on a web page that references the same module. The <code>CreateInstance()</code> function
    154 creates and returns an Instance object derived from the <code>pp::Instance</code> class.</p>
    155 <p>Below is the Instance class from the &#8220;Hello tutorial&#8221; example:</p>
    156 <pre class="prettyprint">
    157 class HelloTutorialInstance : public pp::Instance {
    158  public:
    159   explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance) {}
    160   virtual ~HelloTutorialInstance() {}
    161 
    162   virtual void HandleMessage(const pp::Var&amp; var_message) {}
    163 };
    164 </pre>
    165 <p>As in the example above, the Instance class for your module will likely include
    166 an implementation of the <code>HandleMessage()</code> function. The browser calls an
    167 instance&#8217;s <code>HandleMessage()</code> function every time the JavaScript code in an
    168 application calls <code>postMessage()</code> to send a message to the instance. See the
    169 <a class="reference internal" href="/native-client/devguide/coding/message-system.html"><em>Native Client messaging system</em></a> for more information about
    170 how to send messages between JavaScript code and Native Client modules.</p>
    171 <p>While the <code>CreateModule()</code> factory function, the <code>Module</code> class, and the
    172 <code>Instance</code> class are required for a Native Client application, the code
    173 samples shown above don&#8217;t actually do anything. Subsequent documents in the
    174 Developer&#8217;s Guide build on these code samples and add more interesting
    175 functionality.</p>
    176 </section></section>
    177 
    178 {{/partials.standard_nacl_article}}
    179