Home | History | Annotate | Download | only in coding
      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