OLD | NEW |
(Empty) | |
| 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 topic" id="contents"> |
| 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 </div> |
| 16 <section id="introduction"> |
| 17 <h2 id="introduction">Introduction</h2> |
| 18 <p>Native Client modules do not have a <code>main()</code> function. When a modu
le 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 implemente
d |
| 26 in the browser or in a module. Interfaces starting with <code>PPB_</code> (which
can be |
| 27 read as “Pepper <em>browser</em>”) are implemented in the browser an
d they are called |
| 28 from your module. Interfaces starting with <code>PPP_</code> (“Pepper <em>
plugin</em>”) 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 compone
nts:</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 in
terface.</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 <stdlib.h> |
| 51 #include <string.h> |
| 52 #include "ppapi/c/pp_errors.h" |
| 53 #include "ppapi/c/ppp.h" |
| 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 mod
ule. |
| 57 #include "ppapi/c/ppb_instance.h" |
| 58 #include "ppapi/c/ppp_instance.h" |
| 59 #include "ppapi/c/ppb_input_event.h" |
| 60 #include "ppapi/c/ppp_input_event.h" |
| 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 usin
g. |
| 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 m
odule 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 &Instance_DidCreate, |
| 86 // The definitions of these functions are not shown |
| 87 &Instance_DidDestroy, |
| 88 &Instance_DidChangeView, |
| 89 &Instance_DidChangeFocus, |
| 90 &Instance_HandleDocumentLoad |
| 91 }; |
| 92 return &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 &Instance_HandleInput, |
| 99 }; |
| 100 return &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 g
et_browser) { |
| 109 ppb_instance_interface = (PPB_Instance*)(get_browser(PPB_INSTANCE_INTERF
ACE)); |
| 110 ppb_input_event_interface = (PPB_InputEvent*)(get_browser(PPB_INPUT_EVEN
T_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 compo
nents:</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:Instanc
e</code> |
| 122 class)</li> |
| 123 </ul> |
| 124 <p>In the “Hello tutorial” example (in the <code>getting_started/par
t1</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 be
tween 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 fu
nction |
| 137 returns a Module object derived from the <code>pp::Module</code> class. The brow
ser keeps |
| 138 a singleton of the Module object.</p> |
| 139 <p>Below is the Module class from the “Hello tutorial” 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 bro
wser calls |
| 152 the <code>CreateInstance()</code> method every time it encounters an <code><e
mbed></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 “Hello tutorial” 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& var_message) {} |
| 163 }; |
| 164 </pre> |
| 165 <p>As in the example above, the Instance class for your module will likely inclu
de |
| 166 an implementation of the <code>HandleMessage()</code> function. The browser call
s an |
| 167 instance’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-syste
m.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</cod
e> class, and the |
| 172 <code>Instance</code> class are required for a Native Client application, the co
de |
| 173 samples shown above don’t actually do anything. Subsequent documents in th
e |
| 174 Developer’s Guide build on these code samples and add more interesting |
| 175 functionality.</p> |
| 176 </section></section> |
| 177 |
| 178 {{/partials.standard_nacl_article}} |
OLD | NEW |