1 .. _devcycle-application-structure: 2 3 ##################### 4 Application Structure 5 ##################### 6 7 .. contents:: 8 :local: 9 :backlinks: none 10 :depth: 2 11 12 This chapter of the Developer's Guide describes the general structure of a 13 Native Client application. The chapter assumes you are familiar with the 14 material presented in the :doc:`Technical Overview <../../overview>`. 15 16 17 .. Note:: 18 :class: note 19 20 The "Hello, World" example is used here to illustrate basic 21 Native Client programming techniques. You can find this code in the 22 */getting_started/part1* directory in the Native Client SDK download. 23 24 Application components 25 ====================== 26 27 A Native Client application typically contains the following components: 28 29 * an HTML file; 30 * JavaScript code, which can be included in the HTML file or contained in one or 31 more separate .js files; 32 * CSS styles, which can be included in the HTML file or contained in one or more 33 separate .css files; 34 * a Native Client manifest file (with a .nmf extension) that specifies how to 35 load a Native Client module for different processors; and 36 * a Native Client module, written in C or C++, and compiled into a portable 37 executable file (with a .pexe extension) or (if using the Chrome Web Store), 38 architecture-specific executable files (with .nexe extensions). 39 40 41 Applications that are published in the `Chrome Web Store 42 <https://chrome.google.com/webstore/search?q=%22Native+Client%22+OR+NativeClient+OR+NaCl>`_ 43 also include a Chrome 44 Web Store manifest file ``(manifest.json)`` and one or more icon files. 45 46 .. _html_file: 47 48 HTML file and the <embed> element 49 ================================= 50 51 The ``<embed>`` element in an HTML file triggers the loading of a Native Client 52 module and specifies the rectangle on the web page that is managed by the 53 module. Here is the <embed> element from the "Hello, World" application: 54 55 .. naclcode:: 56 57 <embed id="hello_tutorial" 58 width=0 height=0 59 src="hello_tutorial.nmf" 60 type="application/x-pnacl" /> 61 62 In the ``<embed>`` element: 63 64 name 65 is the DOM name attribute for the Native Client module 66 ("nacl_module" is often used as a convention) 67 id 68 specifies the DOM ID for the Native Client module 69 width, height 70 specify the size in pixels of the rectangle on the web page that is 71 managed by the Native Client module (if the module does not have a 72 visible area, these values can be 0) 73 src 74 refers to the Native Client manifest file that is used to determine 75 which version of a module to load based on the architecture of the 76 user's computer (see the following section for more information) 77 type 78 specifies the MIME type of the embedded content; for Portable Native Client 79 modules the type must be "application/x-pnacl". For architecture-specific 80 Native Client modules the type must be "application/x-nacl" 81 82 83 .. _manifest_file: 84 85 Manifest Files 86 ============== 87 88 Native Client applications have two types of manifest files: a Chrome Web Store 89 manifest file and a Native Client manifest file. 90 91 A **Chrome Web Store manifest file** is a file with information about a web 92 application that is published in the Chrome Web Store. This file, named 93 ``manifest.json``, is required for applications that are published in the 94 Chrome Web Store. For more information about this file see :doc:`Distributing 95 Your Application <../distributing>`. and the `Chrome Web Store manifest file 96 format </extensions/manifest>`_. 97 98 A **Native Client manifest file** is a file that specifies which Native Client 99 module (executable) to load. For PNaCl it specifies a single portable 100 executable; otherwise it specifies one for each of the supported end-user 101 computer architectures (for example x86-32, x86-64, or ARM). This file is 102 required for all Native Client applications. The extension for this file is 103 .nmf. 104 105 Manifest files for applications that use PNaCl are simple. Here is the manifest 106 for the hello world example: 107 108 .. naclcode:: 109 110 { 111 "program": { 112 "portable": { 113 "pnacl-translate": { 114 "url": "hello_tutorial.pexe" 115 } 116 } 117 } 118 } 119 120 121 For Chrome Web Store applications that do not use PNaCl, a typical manifest file 122 contains a `JSON <http://www.json.org/>`_ dictionary with a single top-level 123 key/value pair: the "program" key and a value consisting of a nested 124 dictionary. The nested dictionary contains keys corresponding to the names of 125 the supported computer architectures, and values referencing the file to load 126 for a given architecturespecifically, the URL of the .nexe file, given by the 127 ``"url"`` key. URLs are specified relative to the location of the manifest file. 128 Here is an example: 129 130 .. naclcode:: 131 132 { 133 "program": { 134 "x86-32": { 135 "url": "hello_tutorial_x86_32.nexe" 136 }, 137 "x86-64": { 138 "url": "hello_tutorial_x86_64.nexe" 139 }, 140 "arm": { 141 "url": "hello_tutorial_arm.nexe" 142 } 143 } 144 } 145 146 For applications that use the :ref:`glibc<c_libraries>` 147 library, the manifest file must also contain a "files" key that specifies the 148 shared libraries that the applications use. This is discussed in detail in 149 :doc:`Dynamic Linking and Loading with glibc<../devcycle/dynamic-loading>`. To 150 see some example manifest files, build some of the example applications in the 151 SDK (run ``make`` in the example subdirectories) and look at the generated 152 manifest files. 153 154 In most cases, you can simply use the Python script provided with the SDK, 155 ``create_nmf.py``, to create a manifest file for your application as part of the 156 compilation step (see the Makefile in any of the SDK examples for an 157 illustration of how to do so). The manifest file format is also 158 :doc:`documented<../../reference/nacl-manifest-format>`. 159 160 Modules and instances 161 ===================== 162 163 A Native Client **module** is C or C++ code compiled into a PNaCl .pexe file or 164 a NaCl .nexe file. 165 166 An **instance** is a rectangle on a web page that is managed by a module. An 167 instance may have a dimension of width=0 and height=0, meaning that the instance 168 does not have any visible component on the web page. An instance is created by 169 including an ``<embed>`` element in a web page. The ``<embed>`` element 170 references a Native Client manifest file that loads the appropriate version of 171 the module (either portable, or specific to the end-user's architecture). A 172 module may be included in a web page multiple times by using multiple 173 ``<embed>`` elements that refer to the module; in this case the Native Client 174 runtime system loads the module once and creates multiple instances that are 175 managed by the module. 176 177 178 Native Client modules: A closer look 179 ==================================== 180 181 A Native Client module must include three components: 182 183 * a factory function called ``CreateModule()`` 184 * a Module class (derived from the ``pp::Module`` class) 185 * an Instance class (derived from the ``pp:Instance`` class) 186 187 In the "Hello tutorial" example (in the ``getting_started/part1`` directory of 188 the NaCl SDK), these three components are specified in the file 189 ``hello_tutorial.cc``. Here is the factory function: 190 191 .. naclcode:: 192 193 Module* CreateModule() { 194 return new HelloTutorialModule(); 195 } 196 197 Native Client modules do not have a ``main()`` function. The ``CreateModule()`` 198 factory function is the main binding point between a module and the browser, and 199 serves as the entry point into the module. The browser calls ``CreateModule()`` 200 when a module is first loaded; this function returns a Module object derived 201 from the ``pp::Module`` class. The browser keeps a singleton of the Module 202 object. 203 204 Below is the Module class from the "Hello tutorial" example: 205 206 .. naclcode:: 207 208 class HelloTutorialModule : public pp::Module { 209 public: 210 HelloTutorialModule() : pp::Module() {} 211 virtual ~HelloTutorialModule() {} 212 213 virtual pp::Instance* CreateInstance(PP_Instance instance) { 214 return new HelloTutorialInstance(instance); 215 } 216 }; 217 218 The Module class must include a ``CreateInstance()`` method. The browser calls 219 the ``CreateInstance()`` method every time it encounters an ``<embed>`` element 220 on a web page that references the same module. The ``CreateInstance()`` function 221 creates and returns an Instance object derived from the ``pp::Instance`` class. 222 223 Below is the Instance class from the "Hello tutorial" example: 224 225 .. naclcode:: 226 227 class HelloTutorialInstance : public pp::Instance { 228 public: 229 explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance) {} 230 virtual ~HelloTutorialInstance() {} 231 232 virtual void HandleMessage(const pp::Var& var_message) {} 233 }; 234 235 236 As in the example above, the Instance class for your module will likely include 237 an implementation of the ``HandleMessage()`` function. The browser calls an 238 instance's ``HandleMessage()`` function every time the JavaScript code in an 239 application calls ``postMessage()`` to send a message to the instance. See the 240 :doc:`Native Client messaging system<message-system>` for more information about 241 how to send messages between JavaScript code and Native Client modules. 242 243 The NaCl code is only invoked to handle various browser-issued 244 events and callbacks. There is no need to shut down the NaCl instance by 245 calling the ``exit()`` function. NaCl modules will be shut down when the user 246 leaves the web page, or the NaCl module's ``<embed>`` is otherwise destroyed. 247 If the NaCl module does call the ``exit()`` function, the instance will 248 issue a ``crash`` event 249 :doc:`which can be handled in Javascript<progress-events>`. 250 251 While the ``CreateModule()`` factory function, the ``Module`` class, and the 252 ``Instance`` class are required for a Native Client application, the code 253 samples shown above don't actually do anything. Subsequent chapters in the 254 Developer's Guide build on these code samples and add more interesting 255 functionality. 256