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