OLD | NEW |
1 .. _overview: | 1 .. _overview: |
2 | 2 |
3 ################## | 3 ################## |
4 Technical Overview | 4 Technical Overview |
5 ################## | 5 ################## |
6 | 6 |
7 .. contents:: | 7 .. contents:: |
8 :local: | 8 :local: |
9 :backlinks: none | 9 :backlinks: none |
10 :depth: 2 | 10 :depth: 2 |
11 | 11 |
12 Introduction | |
13 ============ | |
14 | |
15 **Native Client** (NaCl) is an open-source technology for running native | 12 **Native Client** (NaCl) is an open-source technology for running native |
16 compiled code in the browser, with the goal of maintaining the portability | 13 compiled code in the browser, with the goal of maintaining the portability |
17 and safety that users expect from web applications. Native Client expands web | 14 and safety that users expect from web applications. Native Client expands web |
18 programming beyond JavaScript, enabling developers to enhance their web | 15 programming beyond JavaScript, enabling you to enhance your web applications |
19 applications using their preferred language. This document describes some of | 16 using your preferred language. This document describes some of the key benefits |
20 the key benefits and common use cases of Native Client. | 17 and common use cases of Native Client. |
21 | 18 |
22 Google has implemented the open-source `Native Client project | 19 Google has implemented the open-source `Native Client project |
23 <http://www.chromium.org/nativeclient>`_ in the Chrome browser on Windows, Mac, | 20 <http://www.chromium.org/nativeclient>`_ in the Chrome browser on Windows, Mac, |
24 Linux, and Chrome OS. The :doc:`Native Client Software Development Kit (SDK) | 21 Linux, and Chrome OS. The :doc:`Native Client Software Development Kit (SDK) |
25 <sdk/download>`, itself an open-source project, lets developers create web | 22 <sdk/download>`, itself an open-source project, lets you create web applications |
26 applications that use NaCl and run in Chrome across multiple platforms. | 23 that use NaCl and run in Chrome across multiple platforms. |
27 | 24 |
28 A web application that uses Native Client generally consists of a combination of | 25 A Native Client web application consists of JavaScript, HTML, CSS, and a NaCl |
29 JavaScript, HTML, CSS, and a NaCl module that is written in a language supported | 26 module written in a language supported by the SDK. The NaCl SDK currently |
30 by the SDK. The NaCl SDK currently supports C and C++; as compilers for | 27 supports C and C++; as compilers for additional languages are developed, the SDK |
31 additional languages are developed, the SDK will be updated to support those | 28 will be updated. |
32 languages as well. | |
33 | 29 |
34 .. image:: /images/web-app-with-nacl.png | 30 .. figure:: /images/web-app-with-nacl.png |
| 31 :alt: A web application with and without Native Client |
| 32 |
| 33 A web application with and without Native Client |
| 34 |
| 35 Native Client comes in two flavors: traditional (NaCl) and portable (PNaCl). |
| 36 Traditional, which must be distributed through the Chrome Web Store lets you |
| 37 target a specific hardware platform. Portable can run on the open web. A |
| 38 bitcode file that can be loaded from any web server is downloaded to a client |
| 39 machine and converted to hardware-specific code before any execution. For |
| 40 details, see :doc:`NaCl and PNaCl </nacl-and-pnacl>`. |
| 41 |
| 42 .. _why-use-native-client: |
35 | 43 |
36 Why use Native Client? | 44 Why use Native Client? |
37 ====================== | 45 ====================== |
38 | 46 |
39 Native Client open-source technology is designed to run compiled code | 47 Native Client open-source technology is designed to run compiled code |
40 securely inside a browser at near-native speeds. Native Client puts web | 48 securely inside a browser at near-native speeds. Native Client gives web |
41 applications on the same playing field as desktop software---it provides the | 49 applications some advantages of desktop software. Specifically, it provides the |
42 means to fully harness the client's computational resources for applications | 50 means to fully harness the client's computational resources for applications |
43 such as 3D games, multimedia editors, CAD modeling, | 51 such as: |
44 client-side data analytics, and interactive simulations. | |
45 Native Client also aims to give C and C++ (and eventually other languages) the | |
46 same level of portability and safety that JavaScript provides on the web today. | |
47 | 52 |
48 Important benefits of Native Client include: | 53 - 3D games |
| 54 - multimedia editors |
| 55 - CAD modeling |
| 56 - client-side data analytics |
| 57 - interactive simulations. |
| 58 |
| 59 Native Client gives C and C++ (and other languages targeting it) the same level |
| 60 of portability and safety as JavaScript. |
| 61 |
| 62 .. _benefits-of-native-client: |
| 63 |
| 64 Benefits of Native Client |
| 65 ========================= |
| 66 |
| 67 Benefits of Native Client include: |
49 | 68 |
50 * **Graphics, audio, and much more:** Running native code modules that render 2D | 69 * **Graphics, audio, and much more:** Running native code modules that render 2D |
51 and 3D graphics, play audio, respond to mouse and keyboard events, run on | 70 and 3D graphics, play audio, respond to mouse and keyboard events, run on |
52 multiple threads, and access memory directly---all without requiring | 71 multiple threads, and access memory directly---all without requiring the user |
53 the user to install a plugin. | 72 to install a plug-in. |
54 * **Portability:** Writing your applications once and running them on operating | 73 * **Portability:** Writing your applications once and running them on multiple |
55 systems (Windows, Linux, Mac, and Chrome OS) and CPU architectures (x86 and | 74 operating systems (Windows, Linux, Mac, and Chrome OS) and CPU architectures |
56 ARM). | 75 (x86 and ARM). |
57 * **Easy migration path to the web:** Leveraging years of work in existing | 76 * **Easy migration path to the web:** Leveraging years of work in existing |
58 desktop applications. Native Client makes the transition from the desktop to a | 77 desktop applications. Native Client makes the transition from the desktop to |
59 web application significantly easier because it supports C and C++. | 78 a web application significantly easier because it supports C and C++. |
60 * **Security:** Protecting the user's system from malicious or buggy | 79 * **Security:** Protecting the user's system from malicious or buggy |
61 applications through Native Client's double sandbox model. This model offers | 80 applications through Native Client's double sandbox model. This model offers |
62 the safety of traditional web applications without sacrificing performance and | 81 the safety of traditional web applications without sacrificing performance |
63 without requiring users to install a plugin. | 82 and without requiring users to install a plug-in. |
64 * **Performance:** Running at speeds comparable to desktop applications (within | 83 * **Performance:** Running at speeds within 5% to 15% of a native desktop |
65 5-15% of native speed). Native Client also allows applications to harness all | 84 application. Native Client also allows applications to harness all available |
66 available CPU cores via a threading API; this enables demanding applications | 85 CPU cores via a threading API. This enables demanding applications such as |
67 such as console-quality games to run inside the browser. | 86 console-quality games to run inside the browser. |
68 | 87 |
| 88 .. _common-use-cases: |
| 89 |
69 Common use cases | 90 Common use cases |
70 ================ | 91 ================ |
71 | 92 |
72 Typical use cases for Native Client include the following: | 93 Typical use cases for Native Client include the following: |
73 | 94 |
74 * **Existing software components:** With support for C and C++, Native | 95 * **Existing software components:** Native Client lets you repurpose existing |
75 Client lets you to reuse existing software modules in web applications. You | 96 C and C++ software in web applications. You don't need to rewrite and debug |
76 don't need to rewrite and debug code that already works. | 97 code that already works. It also lets your application take advantage of |
| 98 things the browser does well such as handling user interaction and processing |
| 99 events. You can also take advantage of the latest developments in HTML5. |
77 * **Legacy desktop applications:** Native Client provides a smooth migration | 100 * **Legacy desktop applications:** Native Client provides a smooth migration |
78 path from desktop applications to the web. You can port and recompile existing | 101 path from desktop applications to the web. You can port and recompile existing |
79 code for the computation engine of your application directly to Native Client, | 102 code for the computation engine of your application directly to Native Client, |
80 and need rebuild only the user interface and event handling portions for the | 103 and need rebuild only the user interface and event handling portions for the |
81 browser. | 104 browser. |
82 * **Heavy computation in enterprise applications:** Native Client can handle the | 105 * **Heavy computation in enterprise applications:** Native Client can handle the |
83 number crunching required by large-scale enterprise applications. To ensure | 106 number crunching required by large-scale enterprise applications. To ensure |
84 protection of user data, Native Client enables you to build complex | 107 protection of user data, Native Client lets you run complex cryptographic |
85 cryptographic algorithms directly into the browser so that unencrypted data | 108 algorithms directly in the browser so that unencrypted data never goes out |
86 never goes out over the network. | 109 over the network. |
87 * **Multimedia applications:** Codecs for processing sounds, images, and movies | 110 * **Multimedia applications:** Codecs for processing sounds, images, and movies |
88 can be added to the browser in a Native Client module. | 111 can be added to the browser in a Native Client module. |
89 * **Games:** Native Client lets web applications run at close to native | 112 * **Games:** Native Client lets web applications run at close to native |
90 speed, reuse existing multithreaded/multicore C/C++ code bases, and | 113 speed, reuse existing multithreaded/multicore C/C++ code bases, and |
91 access low-latency audio, networking APIs, and OpenGL ES with programmable | 114 access low-latency audio, networking APIs, and OpenGL ES with programmable |
92 shaders. Native Client is a natural fit for running a physics engine or | 115 shaders. Native Client is a natural fit for running a physics engine or |
93 artificial intelligence module that powers a sophisticated web game. | 116 artificial intelligence module that powers a sophisticated web game. |
94 Native Client also enables applications to run unchanged across | 117 Native Client also enables applications to run unchanged across |
95 many platforms. | 118 many platforms. |
96 * **Any application that requires acceleration**: Native Client fits seamlessly | 119 * **Any application that requires acceleration:** Native Client fits seamlessly |
97 into web applications---it's up to you to decide to what extent to use it. | 120 into web applications. It's up to you to decide to what extent to use it. |
98 Use of Native Client covers the full spectrum from complete applications to | 121 Use of Native Client covers the full spectrum from complete applications to |
99 small optimized routines that accelerate vital parts of web applications. | 122 small optimized routines that accelerate vital parts of web applications. |
100 | 123 |
101 .. _link_how_nacl_works: | 124 .. _link_how_nacl_works: |
102 | 125 |
103 How Native Client works | 126 How Native Client works |
104 ======================= | 127 ======================= |
105 | 128 |
106 Native Client is an umbrella name for a set of related software components that | 129 Native Client is an umbrella name for a set of related software components for |
107 provide a way to develop C/C++ applications and run them securely on the web. | 130 developing C/C++ applications and running them securely on the web. At a high |
| 131 level, Native Client consists of: |
108 | 132 |
109 At a high level, Native Client consists of: | 133 * **Toolchains:** collections of development tools (compilers, linkers, etc.) |
110 | 134 that transform C/C++ code to Portable Native Client modules or Native Client |
111 * **Toolchains**: Collections of development tools (compilers, linkers, etc.) | 135 modules. |
112 that transform C/C++ code to Native Client modules. | 136 * **Runtime components:** components embedded in the browser or other host |
113 * **Runtime components**: components embedded in the browser or other | 137 platforms that allow execution of Native Client modules securely and |
114 host platforms that allow execution of Native Client modules | 138 efficiently. |
115 securely and efficiently. | |
116 | 139 |
117 The following diagram shows how these components interact: | 140 The following diagram shows how these components interact: |
118 | 141 |
119 .. image:: /images/nacl-pnacl-component-diagram.png | 142 .. figure:: /images/nacl-pnacl-component-diagram.png |
| 143 :alt: The Native Client toolchains and their outputs |
| 144 |
| 145 The Native Client toolchains and their outputs |
120 | 146 |
121 The left side of the diagram shows how to use Portable Native Client | 147 .. _toolchains: |
122 (PNaCl, pronounced "pinnacle"). Developers use the PNaCl toolchain | |
123 to produce a single, portable (**pexe**) module. At runtime, a translator | |
124 built into the browser translates the pexe into native code for the | |
125 relevant client architecture. Translation occurs before any code is executed. | |
126 | 148 |
127 The right side of the diagram shows how to use (non-portable) Native Client. | 149 Toolchains |
128 Developers use a nacl-gcc based toolchain to produce multiple | 150 ---------- |
129 architecture-dependent (**nexe**) modules, which are packaged into an | 151 |
130 application. At runtime, the browser decides which nexe to load based | 152 A Native Client toolchain consists of a compiler, a linker, an assembler and |
131 on the architecture of the client machine. | 153 other tools that are used to convert C/C++ source code into a module that is |
| 154 loadable by a browser. |
| 155 |
| 156 The Native Client SDK provides two toolchains: |
| 157 |
| 158 * The left side of the diagram shows **Portable Native Client** (PNaCl, |
| 159 pronounced "pinnacle"). An LLVM based toolchain produces a single, portable |
| 160 (**pexe**) module. At runtime an ahead-of-time (AOT) translator, built into |
| 161 the browser, translates the pexe into native code for the relevant client |
| 162 architecture. |
| 163 |
| 164 * The right side of the diagram shows **(non-portable) Native Client**. A GCC |
| 165 based toolchain produces multiple architecture-dependent (**nexe**) modules, |
| 166 which are packaged into an application. At runtime the browser determines |
| 167 which nexe to load based on the architecture of the client machine. |
| 168 |
| 169 The PNaCl toolchain is recommended for most applications. The NaCl-GCC |
| 170 toolchain should only be used for applications that won't be distributed on the |
| 171 open web. |
| 172 |
| 173 .. _security: |
132 | 174 |
133 Security | 175 Security |
134 -------- | 176 -------- |
135 | 177 |
136 Since Native Client permits the execution of native code on client machines, | 178 Since Native Client permits the execution of native code on client machines, |
137 special security measures have to be implemented: | 179 special security measures have to be implemented: |
138 | 180 |
139 * The NaCl sandbox ensures that code accesses system resources only through | 181 * The NaCl sandbox ensures that code accesses system resources only through |
140 safe, whitelisted APIs, and operates within its limits without attempting to | 182 safe, whitelisted APIs, and operates within its limits without attempting to |
141 interfere with other code running either within the browser or outside it. | 183 interfere with other code running either within the browser or outside it. |
142 * The NaCl validator statically analyzes code prior to running it | 184 * The NaCl validator statically analyzes code before running it to make sure it |
143 to make sure it only uses code and data patterns that are permitted and safe. | 185 only uses code and data patterns that are permitted and safe. |
144 | 186 |
145 The above security measures are in addition to the existing sandbox in the | 187 These security measures are in addition to the existing sandbox in the |
146 Chrome browser---the Native Client module always executes in a process with | 188 Chrome browser. The Native Client module always executes in a process with |
147 restricted permissions. The only interaction between this process and the | 189 restricted permissions. The only interaction between this process and the |
148 outside world is through sanctioned browser interfaces. Because of the | 190 outside world is through defined browser interfaces. Because of the |
149 combination of the NaCl sandbox and the Chrome sandbox, we say that | 191 combination of the NaCl sandbox and the Chrome sandbox, we say that |
150 Native Client employs a double sandbox design. | 192 Native Client employs a **double sandbox** design. |
| 193 |
| 194 .. _portability: |
151 | 195 |
152 Portability | 196 Portability |
153 ----------- | 197 ----------- |
154 | 198 |
155 Portable Native Client (PNaCl, prounounced "pinnacle") employs state-of-the-art | 199 Portable Native Client (PNaCl, prounounced "pinnacle") employs state-of-the-art |
156 compiler technology to compile C/C++ source code to a portable bitcode | 200 compiler technology to compile C/C++ source code to a portable bitcode |
157 executable (**pexe**). PNaCl bitcode is an OS- and architecture-independent | 201 executable (**pexe**). PNaCl bitcode is an OS- and architecture-independent |
158 format that can be freely distributed on the web and :ref:`embedded in web | 202 format that can be freely distributed on the web and :ref:`embedded in web |
159 applications<link_nacl_in_web_apps>`. | 203 applications<link_nacl_in_web_apps>`. |
160 | 204 |
161 The PNaCl translator is a component embedded in the Chrome browser; its task is | 205 The PNaCl translator is a component embedded in the Chrome browser; its task is |
162 to run pexe modules. Internally, the translator compiles a pexe to a nexe | 206 to run pexe modules. Internally, the translator compiles a pexe to a nexe |
163 (a native executable for the client platform's architecture), and then executes | 207 (described above), and then executes the nexe within the Native Client sandbox |
164 the nexe within the Native Client sandbox as described above. It also uses | 208 as described above. The translator uses intelligent caching to avoid |
165 intelligent caching to avoid re-compiling the pexe if it was previously compiled | 209 re-compiling the pexe if it was previously compiled on the client's browser. |
166 on the client's browser. | |
167 | 210 |
168 Native Client also supports the execution of nexe modules directly in the | 211 Native Client also supports the execution of nexe modules directly in the |
169 browser. However, since nexes contain architecture-specific machine code, | 212 browser. However, since nexes contain architecture-specific machine code, they |
170 they are not allowed to be distributed on the open web---they can only be | 213 are not allowed to be distributed on the open web. They can only be used as part |
171 used as part of applications and extensions that are installed from the | 214 of applications and extensions that are installed from the Chrome Web Store. |
172 Chrome Web Store. | |
173 | 215 |
174 For more details on the difference between NaCl and PNaCl, see | 216 For more details on the difference between NaCl and PNaCl, see |
175 :doc:`NaCl and PNaCl <nacl-and-pnacl>`. | 217 :doc:`NaCl and PNaCl <nacl-and-pnacl>`. |
176 | 218 |
177 .. _toolchains: | |
178 | |
179 Toolchains | |
180 ---------- | |
181 | |
182 A toolchain is a set of tools used to create an application from a set of | |
183 source files. In the case of Native Client, a toolchain consists of a compiler, | |
184 linker, assembler and other tools that are used to convert an | |
185 application written in C/C++ into a module that is loadable by the browser. | |
186 | |
187 The Native Client SDK provides two toolchains: | |
188 | |
189 * a **PNaCl toolchain** for generating portable NaCl modules (pexe files) | |
190 * a **gcc-based toolchain (nacl-gcc)** for generating non-portable NaCl modules | |
191 (nexe files) | |
192 | |
193 The PNaCl toolchain is recommended for most applications. The nacl-gcc | |
194 toolchain should only be used for applications that will not be distributed | |
195 on the open web. | |
196 | |
197 .. _link_nacl_in_web_apps: | 219 .. _link_nacl_in_web_apps: |
198 | 220 |
199 Native Client in a web application | 221 Structure of a web application |
200 ================================== | 222 ============================== |
201 | 223 |
202 .. _application_files: | 224 .. _application_files: |
203 | 225 |
204 A Native Client application consists of a set of files: | 226 A Native Client application consists of a set of files: |
205 | 227 |
206 * **HTML**, **CSS**, and **JavaScript** files, as in any modern web | 228 * **HTML and CSS:** The HTML file tells the browser where to find the manifest |
207 application. The JavaScript code is responsible for communicating with the | 229 (nmf file) through the embed tag. |
208 NaCl module. | 230 |
209 * A **pexe** (portable NaCl) file. This module uses the :ref:`Pepper | 231 .. naclcode:: |
210 <link_pepper>` API, which provides the bridge to JavaScript and | 232 |
211 browser resources. | 233 <embed name="mygame" src="mygame.nmf" type="application/x-pnacl" /> |
212 * A Native Client **manifest** file that specifies the pexe to load, along with | |
213 some loading options. This manifest file is embedded into the HTML page | |
214 through an ``<embed>`` tag, as shown in the figure below. | |
215 | 234 |
216 .. image:: /images/nacl-in-a-web-app.png | 235 * **Manifest:** The manifest identifies the module to load and specifies |
| 236 options. For example, "mygame.nmf" might look like this: |
| 237 |
| 238 .. naclcode:: |
| 239 |
| 240 {... |
| 241 ... |
| 242 "url": "mygame.pexe", |
| 243 } |
| 244 |
| 245 * **pexe (portable NaCl file):** A compiled Native Client module. It uses the |
| 246 :ref:`Pepper API <link_pepper>`, which provides a bridge to JavaScript and |
| 247 other browser resources. |
| 248 |
| 249 .. figure:: /images/nacl-in-a-web-app.png |
| 250 :alt: Structure of a web application |
| 251 |
| 252 Structure of a web application |
217 | 253 |
218 For more details, see :doc:`Application Structure | 254 For more details, see :doc:`Application Structure |
219 <devguide/coding/application-structure>`. | 255 <devguide/coding/application-structure>`. |
220 | 256 |
221 .. _link_pepper: | 257 .. _link_pepper: |
222 | 258 |
223 Pepper Plugin API | 259 Pepper plug-in API |
224 ----------------- | 260 ------------------ |
225 | 261 |
226 The Pepper Plugin API (PPAPI), called **Pepper** for convenience, is an | 262 The Pepper plug-in API (PPAPI), called **Pepper** for convenience, is an |
227 open-source, cross-platform C/C++ API for web browser plugins. From the point | 263 open-source, cross-platform C/C++ API for web browser plug-ins. Pepper allows a |
228 of view of Native Client, Pepper allows a C/C++ module to communicate with | 264 C/C++ module to communicate with the hosting browser and to access system-level |
229 the hosting browser and get access to system-level functions in a safe and | 265 functions in a safe and portable way. One of the security constraints in Native |
230 portable way. One of the security constraints in Native Client is that modules | 266 Client is that modules cannot make OS-level calls. Pepper provides analogous |
231 cannot make any OS-level calls directly. Pepper provides analogous APIs that | 267 APIs that modules can use instead. |
232 modules can target instead. | |
233 | 268 |
234 You can use the Pepper APIs to gain access to the full array of browser | 269 You can use the Pepper APIs to gain access to the full array of browser |
235 capabilities, including: | 270 capabilities, including: |
236 | 271 |
237 * :doc:`Talking to the JavaScript code in your application | 272 * :doc:`Talking to the JavaScript code in your application |
238 <devguide/coding/message-system>` from the C++ code in your NaCl module. | 273 <devguide/coding/message-system>` from the C++ code in your NaCl module. |
239 * :doc:`Doing file I/O <devguide/coding/file-io>`. | 274 * :doc:`Doing file I/O <devguide/coding/file-io>`. |
240 * :doc:`Playing audio <devguide/coding/audio>`. | 275 * :doc:`Playing audio <devguide/coding/audio>`. |
241 * :doc:`Rendering 3D graphics <devguide/coding/3D-graphics>`. | 276 * :doc:`Rendering 3D graphics <devguide/coding/3D-graphics>`. |
242 | 277 |
243 Pepper includes both a C API and a C++ API. The C++ API is a set of bindings | 278 Pepper includes both a :doc:`C API </c-api>` and a :doc:`C++ API </cpp-api>`. |
244 written on top of the C API. For additional information about Pepper, see | 279 The C++ API is a set of bindings written on top of the C API. For additional |
245 `Pepper Concepts <http://code.google.com/p/ppapi/wiki/Concepts>`_. | 280 information about Pepper, see `Pepper Concepts |
| 281 <http://code.google.com/p/ppapi/wiki/Concepts>`_. |
| 282 |
| 283 .. _versioning: |
246 | 284 |
247 Versioning | 285 Versioning |
248 ========== | 286 ========== |
249 | 287 |
250 Chrome is released on a six week cycle, and developer versions of Chrome are | 288 Chrome is released on a six week cycle, and developer versions of Chrome are |
251 pushed to the public beta channel three weeks before each release. As with any | 289 pushed to the public beta channel three weeks before each release. As with any |
252 software, each release of Chrome may include changes to Native Client and the | 290 software, each release of Chrome may include changes to Native Client and the |
253 Pepper interfaces that may require modification to existing applications. | 291 Pepper interfaces that may require modification to existing applications. |
254 However, modules compiled for one version of Pepper/Chrome should work with | 292 However, modules compiled for one version of Pepper/Chrome should work with |
255 subsequent versions of Pepper/Chrome. The SDK includes multiple versions of the | 293 subsequent versions of Pepper/Chrome. The SDK includes multiple versions of the |
256 Pepper APIs to help developers make adjustments to API changes and take | 294 Pepper APIs to help you make adjustments to API changes and take |
257 advantage of new features: `stable </native-client/pepper_stable>`_, `beta | 295 advantage of new features: `stable </native-client/pepper_stable>`_, `beta |
258 </native-client/pepper_beta>`_ and `dev </native-client/pepper_dev>`_. | 296 </native-client/pepper_beta>`_ and `dev </native-client/pepper_dev>`_. |
259 | 297 |
| 298 .. _where-to-start: |
| 299 |
260 Where to start | 300 Where to start |
261 ============== | 301 ============== |
262 | 302 |
263 The :doc:`Quick Start <quick-start>` document provides links to downloads and | 303 The :doc:`Quick Start <quick-start>` document provides links to downloads and |
264 documentation that should help you get started with developing and distributing | 304 documentation to help you get started with developing and distributing Native |
265 Native Client applications. | 305 Client applications. |
OLD | NEW |