<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ColonelPanic &#187; NPAPI</title>
	<atom:link href="http://colonelpanic.net/category/plugindev/npapi-plugindev/feed/" rel="self" type="application/rss+xml" />
	<link>http://colonelpanic.net</link>
	<description>Dumping our corps so you don&#039;t have to</description>
	<lastBuildDate>Mon, 30 Jan 2012 17:50:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Building a firefox plugin &#8211; part four</title>
		<link>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/</link>
		<comments>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 03:41:01 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=520</guid>
		<description><![CDATA[The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I [...]]]></description>
			<content:encoded><![CDATA[<p>The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I ended up reviewing for an employer where the original author had not previously met me. I never inteded those to be the end of the series, but it has been quite some time since I last posted an update.  The main reason for this is that for all but a few uses &#8212; android in particular &#8212; I no longer recommend anyone write a NPAPI plugin from scratch. The reason for this is that the popular <a href="http://www.firebreath.org">FireBreath</a> framework makes all of this so easy and fixes so many edge cases in different browser versions that it isn&#8217;t worth doing it by hand anymore.</p>
<p>Yes, I wrote <a href="http://www.firebreath.org">FireBreath</a>. A lot of others have contributed.</p>
<h2>A different approach to learning NPAPI</h2>
<p>Now that I have a good example already up and running, it seems pointless to keep trying to describe things with words and code snippets when I can simply walk you through what I have done &#8212; what is in use and works well. To that end, and in hopes that it will foster more capable NPAPI developers to help with FireBreath development (we still don&#8217;t support printing, for example), I have created a series of 5 minute screencasts providing a brief overview of FireBreath&#8217;s NPAPI framework.</p>
<p>I don&#8217;t expect that this is as comprehensive as it should be; I&#8217;m hoping that comments will help me see what future segments I should create.  I have posted these screencasts on youtube and will link to them from here. You can also find a more complete series that includes this one <a href="http://www.firebreath.org/display/documentation/FireBreath+development+video+tutorials">on the FireBreath website</a>.</p>
<p><iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/ehHfsxj2xSk" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/VbHW4HvitIg" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/RtPyEpiTFxY" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/c17kvVxoNGU" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/SQtduyKCAZ8" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/4NxLMDUHufE" frameborder="0"><br />
</iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Browser Plugins vs Extensions – the difference</title>
		<link>http://colonelpanic.net/2010/08/browser-plugins-vs-extensions-the-difference/</link>
		<comments>http://colonelpanic.net/2010/08/browser-plugins-vs-extensions-the-difference/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 13:42:01 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[bho]]></category>
		<category><![CDATA[browser plugin]]></category>
		<category><![CDATA[extension]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=312</guid>
		<description><![CDATA[Overloaded terms One of the least understood concepts in the Browser Plugin world is &#8212; browser plugins.  What they are, and even more: what they are not.  Probably at least once a week I answer a question somewhere on a forum or on the comments on this blog and say &#8220;You can&#8217;t do that with [...]]]></description>
			<content:encoded><![CDATA[<h2>Overloaded terms</h2>
<p>One of the least understood concepts in the Browser Plugin world is &#8212; browser plugins.  What they are, and even more: what they are not.  Probably at least once a week I answer a question somewhere on a forum or on the comments on this blog and say &#8220;You can&#8217;t do that with a plugin; you need an extension&#8221;.</p>
<p>Many people confuse plugins and extensions in the browser world. They sound like they should be the same thing, but in fact they are very different.</p>
<h2>What you can do with a plugin</h2>
<p>A plugin is, quite simply, a third party library that &#8220;plugs in&#8221; to the browser that can be embedded inside a web page using an &lt;embed&gt; tag or a &lt;object&gt; tag.  Many of them then draw pretty pictures or animations, though that&#8217;s not required.  Many allow you to talk to them through javascript, though that&#8217;s not required.  In short, a plugin affects only a specific page in which it is placed.</p>
<p>Examples of common plugins include:</p>
<ul>
<li><span id="more-312"></span>Macromedia Flash</li>
<li>Microsoft Silverlight</li>
<li>Apple Quicktime</li>
<li>Adobe Reader (at least this includes a plugin in addition to the rest of the application)</li>
</ul>
<p>Some plugins respond to a mime type and can run in place of the page, such as Adobe Reader, which allows you to view PDF files in your web browser.  Again, however, it affects only that page, and no others.  In Firefox, Chrome, Opera, and Safari, these plugins are usually called &#8220;NPAPI plugins&#8221;, since they are written using the <a title="NPAPI on wikipedia" href="http://en.wikipedia.org/wiki/NPAPI">NPAPI</a>.  In Safari, you could also use a <a href="http://developer.apple.com/mac/library/documentation/InternetWeb/Conceptual/WebKit_PluginProgTopic/WebKitPluginTopics.html">Webkit Plugin</a>.  In Internet Explorer you would do this with an ActiveX Control.</p>
<h2>What a plugin cannot do</h2>
<p>Plugins have to either handle a mime type or be embedded into a web page.  They don&#8217;t get put there automatically. They don&#8217;t create toolbars.  They don&#8217;t affect browser menus.  They don&#8217;t know about tabs, or even about other pages in the same browser process.  They don&#8217;t make coffee, tea, or hot chocolate, though they could be written to control an external appliance to do so if you really wanted.  They don&#8217;t automatically process the content of every web page loaded.</p>
<p>&#8220;But wait!&#8221; I hear you all cry.  &#8220;We have seen these magical things done! (well, except the hot chocolate machine)&#8221;</p>
<p>&#8220;Yes,&#8221; I reply.  &#8220;Those are extensions.&#8221;</p>
<h2>Extensions</h2>
<p>Extensions, or &#8220;add-ons&#8221;, can often do these magical things.  They can add onto the browser UI, process pages that the browser loads.  They do all sorts of things.  However, they are not the same thing as plugins; they affect the web browser itself, not really the page.  They may affect a page as well, of course.  In fact, you can even put a plugin inside an extension, at least in Firefox.  However, if you write an extension for Firefox, you&#8217;ll probably have to write it again for Chrome, Safari, and IE&#8230; one for each.  Perhaps there is a framework out there for writing portable extensions, though.  It&#8217;s not really my area of expertise, so I don&#8217;t know.</p>
<p>Examples of extensions / add-ons:</p>
<ul>
<li><a href="http://www.downthemall.net/">DownThemAll</a> for Firefox</li>
<li><a href="http://getfirebug.com/" target="_blank">Firebug</a> for Firefox</li>
<li><a href="https://chrome.google.com/extensions/detail/kcnhkahnjcbndmmehfkdnkjomaanaooo" target="_blank">Google Voice extension</a> for Chrome</li>
<li><a href="http://kanab.hys.cz/let-there-be-comic-sans/">Let there be Comic Sans</a> for Safari</li>
</ul>
<p>And many, many, many more.  Extensions can be written in different languages depending on the browser.  In Firefox you can write them in C++ or javascript, and on Internet Explorer you write them as special ActiveX controls called <a href="http://en.wikipedia.org/wiki/Browser_Helper_Object">Browser Helper Objects</a>, or BHOs.</p>
<h2>An extension could contain a plugin, but a plugin can&#8217;t contain an extension</h2>
<p>One very common way to install a plugin in Firefox is to use a .xpi file.  <strong><em>This is an extension</em></strong>.  It may have a NPAPI plugin inside of it, but it is still an extension.  It will not work on other web browsers, even though your NPAPI plugin may work perfectly fine on Chrome and Safari if installed in another way.</p>
<p>Conversely, a plugin by nature does not include an extension.</p>
<h2>FireBreath</h2>
<p>Nearly a year ago now I began a project called FireBreath, which is a cross-platform browser plugin architecture.  FireBreath is, frankly, awesome. You can literally get a plugin up and going in under 10 minutes if you already have everything installed.  That means you can spend your time doing other more important things, like actually developing your functionality, rather than spending all your time figuring out how to deal with the plugin APIs.</p>
<p>That said, FireBreath is a cross-platform browser <span style="text-decoration: underline;"><em><strong>PLUGIN</strong></em></span> framework.  It does not create extensions.  It will never be able to create extensions.  If you need an extension, you need something else.</p>
<h2>When not to use a plugin</h2>
<p>Finally, and this is a topic that people seem to think is a little strange coming from me, there are many cases when it is not a good idea to use a browser plugin.  In fact, a good rule of thumb is that if you can do what you need to do without one, don&#8217;t use one.</p>
<p>Why?</p>
<ul>
<li>There are no really good ways to install browser plugins that will work 100% of the time
<ul>
<li>XPI install only works on one profile in firefox</li>
<li>CAB install only works in Internet Explorer and is sometimes a little unreliable</li>
<li>ClickOnce works only in Windows and only if .Net is installed</li>
<li>Java installers only work reliably and consistently on Mac OS</li>
<li>MSI or EXE installers while being the best method IMHO require a little more work on the part of the user, and the average user is&#8230; less savvy than you are, shall we say.</li>
</ul>
</li>
<li>Plugins have to take into account a large range of hardware types
<ul>
<li>If you use graphics libraries such as OpenGL or DirectX keep in mind that every graphics card works a little differently with these technologies.  You will run into weird cases where your plugin doesn&#8217;t work on someone&#8217;s computer.  If your luck is like mine, that computer will belong to an executive at a fortune 500 company (yes, that happened to me.  no, it wasn&#8217;t fun)</li>
</ul>
</li>
<li>Plugins don&#8217;t work until they have been installed
<ul>
<li>This is a major limiting factor to uptake of your site.  Many users don&#8217;t want to install yet another plugin on their machine, and many get lost in the incredibly complicated task of downloading and running the installer.</li>
</ul>
</li>
</ul>
<h2>Moving on</h2>
<p>If all of those things haven&#8217;t convinced you that what you want isn&#8217;t actually a browser plugin &#8212; great!  That&#8217;s why I&#8217;m still posting about this stuff.  Despite all the reasons not to use a plugin, there are also a lot of cases where it&#8217;s a good idea. Browesr plugin development can be a lot of fun!  Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/08/browser-plugins-vs-extensions-the-difference/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Firefox 3.6 has removed support for XPCOM plugins!</title>
		<link>http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/</link>
		<comments>http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 16:19:02 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[xpcom]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/</guid>
		<description><![CDATA[Most who are deep in the plugin world already know this, but I will repeat it quickly for those who only dabble: Firefox 3.6 has removed support for XPCOM plugins. This means that if you use XPCOM for your javascript interface (i.e. you have an IDL file on your npapi plugin, you us nsScriptablePeer, etc) [...]]]></description>
			<content:encoded><![CDATA[<p>Most who are deep in the plugin world already know this, but I will repeat it quickly for those who only dabble:</p>
<p>Firefox 3.6 has removed support for XPCOM plugins.</p>
<p>This means that if you use XPCOM for your javascript interface (i.e. you have an IDL file on your npapi plugin, you us nsScriptablePeer, etc) your plugin will no longer be able to communicate with javascript in Firefox 3.6.</p>
<p>Thus I repeat advice that I have given in the past:  Never, never, *never*, *ever* use XPCOM for your javascript interface in your plugin.</p>
<p>There might conceivably be reasons to use other aspects of XPCOM in a plugin, that might even work in other browsers.  At present, I don&#8217;t know of them.  Please enlighten me if there are (cookies?).</p>
<p>Oh, yeah, and FireBreath now has linux and mac support (experimental) as well as windows support (stable).  Come join the fun.  http://firebreath.googlecode.com</p>
<p>Thank you. :-P</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Cross-Browser Scripting – Part one</title>
		<link>http://colonelpanic.net/2009/12/cross-browser-scripting-part-one/</link>
		<comments>http://colonelpanic.net/2009/12/cross-browser-scripting-part-one/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 05:31:04 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[browser plugin]]></category>
		<category><![CDATA[Common Scripting Interface]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[IDispatch]]></category>
		<category><![CDATA[IDispatchEx]]></category>
		<category><![CDATA[npobject]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=117</guid>
		<description><![CDATA[The Problem: I&#8217;ll be up-front about something here; I don&#8217;t particularly like ActiveX.  I understand a lot of the reasons for creating it, and I won&#8217;t go so far as to claim that it shouldn&#8217;t exist or anything like that; in fact, it does very well for certain types of things.  The main thing I [...]]]></description>
			<content:encoded><![CDATA[<h1>The Problem:</h1>
<p>I&#8217;ll be up-front about something here; I don&#8217;t particularly like ActiveX.  I understand a lot of the reasons for creating it, and I won&#8217;t go so far as to claim that it shouldn&#8217;t exist or anything like that; in fact, it does very well for certain types of things.  The main thing I don&#8217;t like about it is the complexity; it&#8217;s not something that you just pick up and start using one day.  You have to do a lot of research to understand what is happening, and though I&#8217;ve been working on ActiveX Controls hosted in Internet Explorer for over a year now, there is still a lot I don&#8217;t understand about what is really happening under the covers.</p>
<p>Because of this, I am a big fan of NPAPI.  I think it&#8217;s a great technology.  It&#8217;s simple.  It&#8217;s straightforward.  It provides an interface for one purpose, and that is to allow 3rd party developers to write browser plugins.  It&#8217;s great.  But, there is a problem: in my world, you can&#8217;t just say &#8220;I like Firefox better than IE, so I&#8217;m not going to support IE.&#8221;  Why?  I will make no claims here about security, usability, viability, or even disability of any browsers.  I will simply refer to one statistic: according to the <a title="W3Schools browser stats" href="http://www.w3schools.com/browsers/browsers_stats.asp" target="_blank">w3schools browser statistics</a>, Internet Explorer accounted for over 25% of the total web traffic every month last year.</p>
<p>So we find the classic challenge of all browser plugin developers: Internet Explorer only supports ActiveX controls, other browsers support NPAPI, and a plugin written for one isn&#8217;t neccesarily going to be easy to just port to the other.  Thus was born <a title="Firebreath overview" href="http://colonelpanic.net/2009/12/firebreath-ready-for-testing/">FireBreath</a>, in an attempt to solve this issue.  Today, however, I want to address only one piece of the solution that we use in FireBreath:  How to create a scripting interface that will be &#8220;write once, run anywhere&#8221; on web browsers.</p>
<h1><span id="more-117"></span>Common Scripting Interface</h1>
<p>When I first began working on plugins, I worked on a project that had 3 seperate defintions of the javascript interface to the plugin.  One was for Mac, one for Internet Explorer on Windows, and one for Firefox on Windows.  The IE version was defined in an ActiveX .idl file and implemented in an ActiveX object.  The Firefox/win one was defined in an &#8220;XPCOM&#8221; .idl file and implemented in a nsScriptablePeer object (copied from a sample plugin from the mozilla source), and the Mac one was defined using NPRuntime and wrapped the XPCOM class.</p>
<p>This was, in short, a nightmare.</p>
<p>The problem I was initially trying to solve is that we had some APIs that had to be used differently on Mac and Windows, and they differed in less noticeable ways between Firefox and IE on Windows.  Don&#8217;t get me wrong &#8212; it all worked just fine.  However, from a maintenance point of view, this was certainly not optimal.  I could give a lot of meaningless history here, but eventually I came up with an idea that I dubbed (at that company) the Common Scripting Interface &#8212; a class that contained all the aspects that a good javascript object would need, but was not specific to any one browser.</p>
<h1>Down with the IDL</h1>
<p>Okay, this is where I&#8217;m going to start raising a lot of eyebrows.  I respectfully submit that using an IDL, as it is defined by Internet Explorer, is generally a bad idea on a control intended to be used from Javascript.  Why?  Simply put, Javascript is a dynamic language; when you pass parameters around, they are not type constrained.  Most javascript functions don&#8217;t care if you give them an integer, a string, a bool, or something else; they just use the parameters they are given.  Of course it&#8217;s a bit more complicated than that, but Javascript inherently is dynamic.  Thus, it can be important to have the ability to use a dynamic interface on a plugin that interfaces with it.</p>
<p>I hasten to remind you at this point that making an interface dynamic just for the sake of it being dynamic is a bad idea.  However, there are many use cases where you may have members (particularly properties that expose other javascript objects) that may only be named and become accessible at runtime; it&#8217;s too late to add something to the IDL.  I believe this is part of the reason that we have settled on NPRuntime on Gecko-based browsers, and Microsoft created an IDispatchEx interface to better support it on ActiveX.  Thus, we have all the tools we need to create a dynamic interface, and I have loosely patterned it after the NPAPI/NPRuntime interface, which I consider to be a fairly good interface for browser plugins.</p>
<h1>What is JSAPI?</h1>
<p>If you have looked at all at the FireBreath project that I have been working on for the last several months, you may have looked at or seen reference to the JSAPI class.  JSAPI stands for Javascript API.  JSAPI is intended to be a Javascript compatible object written in C++.  It relies heavily on the FB::variant class, which essentially is a class that you can put any datatype in.  If there is enough interest, I can blog more about that type later, but suffice it to say it&#8217;s very similar to boost::any but with data conversion tools built in.  A JSAPI object (an object that extends FB::JSAPI) provides all functionality that a Javascript object should, whether it is used or not.</p>
<h2>What does a Javascript object do?</h2>
<p>Let&#8217;s take a big step backwards now.  Forget anything you know about Browser Plugins or ActiveX Controls.  Forget anything you even know about C++, Java, C#, Logo, or any other language, even, except Javascript, HTML, DHTML, and CSS.  Those are the tools of the browser.  When we design the interface for a Browser Plugin, we shouldn&#8217;t be thinking like a C++ developer.  We should be looking at it the way we would if we were writing an object in Javascript; we should provide the interfaces that we would expect to find, and use the tools and syntax that we would expect to find in Javascript.</p>
<p>So, let&#8217;s look at what a Javascript object can do:</p>
<ul>
<li>Javascript objects can have methods that accept parameters and return a value
<ul>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> coolData <span style="color: #339933;">=</span> plugin.<span style="color: #660066;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;right now&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
</ul>
</li>
<li>Javascript objects can expose properties that a caller can get or set:
<ul>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oldName <span style="color: #339933;">=</span> plugin.<span style="color: #000066;">name</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">plugin.<span style="color: #000066;">name</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Some cool name&quot;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
</ul>
</li>
<li>Javascript objects can provide events, to which a caller can attach an event handler in the syntax of their browser:
<ul>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">plugin.<span style="color: #660066;">addEventHandler</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;click&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;The user clicked on me! Ouch!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">plugin.<span style="color: #660066;">attachEvent</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;onclick&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;The user clicked on me! Ouch!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
</ul>
</li>
</ul>
<p>When you write it out like this, it doesn&#8217;t seem like much; remember, though, that a property of a javascript object could return any primitive datatype, an array, or even another javascript object, itself containing methods, properties, and events.</p>
<h2>The JSAPI Interface</h2>
<p>One additional thing to remember about a Javascript Object (now taking into account what we know about C++ as well) is that we don&#8217;t control the lifecycle of a javascript object.  What that means is that your plugin may go away before Javascript is done with the object that you gave it.  So, if that object uses any references to your plugin, (And what plugin javascript object wouldn&#8217;t? It&#8217;s the interface to the page, right?) you need to have a way to deal with not only cleaning up your object even after the plugin goes away, but making sure that the javascript object somehow finds out that the object it depends on is gone and invalidates itself in some way.  One way to do that is by using Shared pointers and Weak pointers, but that&#8217;s a topic for another day.</p>
<p>Like the NPObject and IDispatch types that provide its interface with the browser, JSAPI is reference counted, so that it will get destroyed whenever the browser.  Here are the method prototypes from JSAPI.h to satisfy the requirements mentioned above.  You can also look at <a title="JSAPI.h source" href="http://code.google.com/p/firebreath/source/browse/src/ScriptingCore/JSAPI.h" target="_blank">the full source of JSAPI.h</a> if you want.</p>
<h3>Methods</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// ...</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> HasMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> methodName<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> variant Invoke<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> methodName, std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000040;">&amp;</span>lt<span style="color: #008080;">;</span>variant<span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span> args<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// ...</span></pre>
</div>
</div>
<p>Not much is required; one call to find out if the method exists, one to invoke the method.  Notice that the arguments is passed in a STL vector of type variant; you can pass any datatypes in here, but that will be limited by the Browser-level wrapper that converts the arguments from the browser datatype (VARIANT on IE, NPVariant on firefox) to the JSAPI variant datatype.  I&#8217;ll discuss this in more detail in a later post.</p>
<h3>Properties</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// ...</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> HasProperty<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> propertyName<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> HasProperty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> idx<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">virtual</span> variant GetProperty<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> propertyName<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> variant GetProperty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> idx<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> SetProperty<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> propertyName, <span style="color: #0000ff;">const</span> variant value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> SetProperty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> idx, <span style="color: #0000ff;">const</span> variant value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// ...</span></pre>
</div>
</div>
<p>You&#8217;ll notice one strange thing right off the bat here; there are two of each method.  One takes a std::string for the first parameter, one takes an int.  Any thoughts on why?</p>
<p>Imagine the following code:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> plugin.<span style="color: #660066;">files</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>plugin.<span style="color: #660066;">files</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre>
</div>
</div>
<p>This is a pretty standard piece of javascript code, right?  Array access notation is pretty common in Javascript.  Javascript, however, treats everything as an object of one kind or another. An array to javascript is really just an object with numeric properties.  Similarly, we need to be able to support numeric properties for array style access.  That is why we have extra property methods for a property identified by an &#8220;int&#8221;.</p>
<h3>Events</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// ...</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> registerEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name, BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> unregisterEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name, BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> registerEventInterface<span style="color: #008000;">&#40;</span>BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> unregisterEventInterface<span style="color: #008000;">&#40;</span>BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> BrowserObjectAPI <span style="color: #000040;">*</span>getDefaultEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> setDefaultEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name, BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// Used to fire an event to the listeners attached to this JSAPI</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> FireEvent<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> eventName, std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000040;">&amp;</span>lt<span style="color: #008080;">;</span>variant<span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// ...</span></pre>
</div>
</div>
<p>Events are by far the most difficult piece of this whole class; we have to make allowances for multiple methods of registering events and multiple browsers&#8217; methods for keeping track of the handlers. The BrowserObjectAPI type that you see used here is also a JSAPI object, but one that wraps a browser object (an NPObject or a IDispatch object, depending on the browser).</p>
<p>There are three different ways an event can be registered (at this point in time):</p>
<ol>
<li>Through a &#8220;user-defined&#8221; event registering method implemented by our browser scripting object wrapper (this is used by all objects on firefox and all but the root object on IE).
<ul>
<li>The BrowserObjectAPI object will essentially be a method that we can invoke by calling InvokeAsync with empty string (&#8220;&#8221;) as the method name</li>
</ul>
</li>
<li>Through the Connection Point interface on an ActiveX Control (obviously used on the root object in IE)
<ul>
<li>The BrowserObjectAPI object will be an object on which we can invoke a method of the same name as the event it is attached to</li>
</ul>
</li>
<li>Through a property of the same name as the event (old-style javascript events, as in &#8220;document.onload = &#8230;.&#8221;
<ol>
<li>The BrowserObjectAPI object will essentially be a method that we can invoke by calling InvokeAsync with empty string (&#8220;&#8221;) as the method name</li>
</ol>
</li>
</ol>
<p>These three types are the reason that we have three different register/unregister methods on the browser for events.  When FireEvent is called by the JSAPI child object (that you write), it iterates through all possible event handlers and invokes them asynchronously.  (Events have to be invoked on the main UI thread of the plugin, so the InvokeAsync call on BrowserObjectAPI automatically makes sure that is where it gets called; hence it&#8217;s async).</p>
<h1>Next time</h1>
<p>We have discussed and looked at the basic needs of the JSAPI object.  Part two will discuss the <a title="COMJavascriptObject.h source" href="http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/COMJavascriptObject.h">COMJavascriptObject</a> class and the <a title="JSAPI_IDispatch.h source" href="http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/JSAPI_IDispatchEx.h">JSAPI_IDispatch</a> helper class that constitute the interface between ActiveX and our JSAPI interfaces.  Part three will cover the <a title="NPJavascriptObject.h source" href="http://code.google.com/p/firebreath/source/browse/src/NpapiPlugin/NPJavascriptObject.h">NPJavascriptObject</a> that provides the interface between NPRuntime and JSAPI.  Feel free to read ahead in the source =]</p>
<p>In the mean time, if you like where this is going and want to play with FireBreath and see JSAPI in action for yourself, there are some <a title="Creating a new Plugin Project with FireBreath" href="http://code.google.com/p/firebreath/wiki/CreatingANewPluginProject">really easy getting started instructions</a> on the <a title="Firebreath project home page" href="http://code.google.com/p/firebreath/" target="_blank">FireBreath project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/12/cross-browser-scripting-part-one/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Memory management in NPAPI</title>
		<link>http://colonelpanic.net/2009/12/memory-management-in-npapi/</link>
		<comments>http://colonelpanic.net/2009/12/memory-management-in-npapi/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 21:45:13 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=111</guid>
		<description><![CDATA[Introduction Ever since I started this series of posts on NPAPI and plugins, I have started receiving occasional emails requesting additional help with aspects of NPAPI that are particularly confusing.  With full-time work, FireBreath development, and a 6 month old baby to take care of, I often don&#8217;t have as much time as I&#8217;d like [...]]]></description>
			<content:encoded><![CDATA[<h1>Introduction</h1>
<p>Ever since I started this series of posts on NPAPI and plugins, I have started receiving occasional emails requesting additional help with aspects of NPAPI that are particularly confusing.  With full-time work, FireBreath development, and a 6 month old baby to take care of, I often don&#8217;t have as much time as I&#8217;d like to give these questions the attention that they deserve.  One that I got today struck me as being a particularly confusing bit for many people, and one that I hope I can answer briefly, so I&#8217;m going to give it a shot.  I&#8217;m still kinda hoping to get to the point that I can explain smaller bits with shorter posts, which will make it easier for me to post new material more often.</p>
<h1><a title="Gecko SDK documentation for NPObject" href="https://developer.mozilla.org/en/NPObject"><span id="more-111"></span>NPObject</a> and <a title="Gecko SDK documentation for NPVariant" href="https://developer.mozilla.org/en/NPVariant">NPVariant</a></h1>
<p>In general, there are two datatypes that are used by the browser to pass information.  NPObjects are, for those who haven&#8217;t read <a title="Building a firefox plugin -- part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-%e2%80%93-part-three/" target="_blank">my previous post on NPAPI</a>, the basic datatype for anything that is scriptable &#8212; that is, javascript objects and objects that can talk to javascript.  NPVariant is the datatype that is used to pass parameters and values to and from NPObjects.</p>
<p><strong>As a general rule of thumb</strong>: Any time the browser gives you something as a return value, you need to release it using browser API calls.  Any time you return something to the browser as a return value, assume that the browser will release it using browser API calls.</p>
<h2>NPObject</h2>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> NPObject <span style="color: #008000;">&#123;</span>
  NPClass <span style="color: #000040;">*</span>_class<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">uint32_t</span> referenceCount<span style="color: #008080;">;</span>
  <span style="color: #ff0000; font-style: italic;">/*
   * Additional space may be allocated here by types of NPObjects
   */</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>There are three important NPN_ (browser API) functions that you need to understand when using a NPObject:</p>
<ul>
<li><a title="Gecko SDK documentation for NPN_CreateObject" href="https://developer.mozilla.org/en/NPN_CreateObject">NPN_CreateObject</a> &#8211; Creates an NPObject and returns a reference to it (see <a title="Building a firefox plugin -- part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-%e2%80%93-part-three/" target="_blank">part three of Building a firefox Plugin</a>); sets referenceCount to 1</li>
<li><a title="Gecko SDK documentation for NPN_RetainObject" href="https://developer.mozilla.org/en/NPN_RetainObject">NPN_RetainObject</a> &#8211; Increments referenceCount</li>
<li><a title="Gecko SDK documentation for NPN_ReleaseObject" href="https://developer.mozilla.org/en/NPN_ReleaseObject">NPN_ReleaseObject</a> &#8211; Decrements referenceCount and destroys the object if referenceCount hits 0</li>
</ul>
<h3>NPObject creation</h3>
<p>It is important to understand that NPN_CreateObject will initialize referenceCount to 1 before returning it.  Thus, if you only plan for it to be used once, you do not need to call NPN_RetainObject on the newly created NPObject.  To do so anyway could prevent the object from ever being released (which could be bad).  A question was ask about the npruntime sample in the gecko source code, and why it calls NPN_RetainObject after NPN_CreateObject.  Here is the function in question:</p>
<p>(from mozilla_central/modules/plugin/sdk/samples/npruntime/plugin.cpp):</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPObject <span style="color: #000040;">*</span>
CPlugin<span style="color: #008080;">::</span><span style="color: #007788;">GetScriptableObject</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>m_pScriptableObject<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        m_pScriptableObject <span style="color: #000080;">=</span> NPN_CreateObject<span style="color: #008000;">&#40;</span>m_pNPInstance, GET_NPOBJECT_CLASS<span style="color: #008000;">&#40;</span>ScriptablePluginObject<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>m_pScriptableObject<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        NPN_RetainObject<span style="color: #008000;">&#40;</span>m_pScriptableObject<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> m_pScriptableObject<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>It&#8217;s easy to see how you could get confused here.  Why should we call Retain on it if the referenceCount has already been set to 1?  Simply put, the initial referenceCount is to account for the fact that we&#8217;re storing the NPObject in this-&gt;m_pScriptableObject &#8212; we&#8217;ll need to call NPN_ReleaseObject in the destructor to release it.  Why do we call Retain, then?  Because we&#8217;re returning an NPObject to the browser (in this case, it is only called in response to a NPP_GetValue with NPPVpluginScriptableNPObject as the NPPVariable), and the browser will expect it to have been properly initialized and will call NPN_ReleaseObject when it&#8217;s done with it.</p>
<p>Remember the rule of thumb mentioned above:  Any time you return a NPObject as a return value to the browser, the browser will release it when it&#8217;s done.  This means it has to have been retained first!  If you weren&#8217;t going to keep a copy of the NPObject, then you wouldn&#8217;t need to call retain again; just create it and return it each time.  This makes it a little trickier to keep state, unless you have another object that gives the NPObject it&#8217;s brains, like is used in <a title="Firebreath project home page" href="http://firebreath.googlecode.com" target="_blank">FireBreath</a>.</p>
<p style="padding-left: 30px;">(Firebreath&#8217;s NPObject code is in <a title="NPJavascriptObject.cpp source" href="http://code.google.com/p/firebreath/source/browse/src/NpapiPlugin/NPJavascriptObject.cpp?r=d5953ffb9a8816657ba9c8a149f04db3ec981db0">NPJavascriptObject.cpp</a> and <a title="NPJavascriptObject.h source" href="http://code.google.com/p/firebreath/source/browse/src/NpapiPlugin/NPJavascriptObject.h?r=d5953ffb9a8816657ba9c8a149f04db3ec981db0">NPJavascriptObject.h</a>, and the object it wraps extends <a title="JSAPI.h source" href="http://code.google.com/p/firebreath/source/browse/src/ScriptingCore/JSAPI.h?r=d5953ffb9a8816657ba9c8a149f04db3ec981db0">JSAPI</a>, with the <a title="JSAPI.cpp source" href="http://code.google.com/p/firebreath/source/browse/src/ScriptingCore/JSAPI.cpp?r=d5953ffb9a8816657ba9c8a149f04db3ec981db0">implementation here</a>.  The JSAPI provides a platform independent abstraction for providing a scriptable object; in other words, you implement your methods and properties in JSAPI and it works everywhere.  There is a good example of a JSAPI object in <a title="FBTestPluginAPI.h source" href="http://code.google.com/p/firebreath/source/browse/examples/FBTestPlugin/FBTestPluginAPI.h?r=d5953ffb9a8816657ba9c8a149f04db3ec981db0">FBTestPluginAPI.h</a> and <a title="FBTestPluginAPI.cpp source" href="http://code.google.com/p/firebreath/source/browse/examples/FBTestPlugin/FBTestPluginAPI.cpp?r=d5953ffb9a8816657ba9c8a149f04db3ec981db0">FBTestPluginAPI.cpp</a>)</p>
<h2>NPVariants</h2>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPVariant <span style="color: #008000;">&#123;</span>
  NPVariantType type<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">union</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> boolValue<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int32_t</span> intValue<span style="color: #008080;">;</span>
    double_t doubleValue<span style="color: #008080;">;</span>
    NPString stringValue<span style="color: #008080;">;</span>
    NPObject <span style="color: #000040;">*</span>objectValue<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span> value<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> NPVariant<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>The next step in dealing with memory management is to understand how NPVariants work, are allocated, and are released.  NPVariants are used as parameters and return values on NPObject methods.  As you can see from the NPVariant structure above, most NPVariant types are primitives, and thus don&#8217;t need any special memory management.  The two types you need to worry about are the <a title="Gecko SDK documentation for NPString" href="https://developer.mozilla.org/en/NPString">NPString</a> and the NPObject.</p>
<p>There are three important NPN_ (browser API) functions that relate to NPStrings:</p>
<ul>
<li><a title="Gecko SDK documentation for NPN_MemAlloc" href="https://developer.mozilla.org/en/NPN_MemAlloc">NPN_MemAlloc</a> &#8211; Allocates a chunk of memory controlled by the browser and returns a pointer to it (compare to malloc)</li>
<li><a title="Gecko SDK documentation for NPN_MemFree" href="https://developer.mozilla.org/en/NPN_MemFree">NPN_MemFree</a> &#8211; Frees a chunk of memory controlled by the browser (compare to free)</li>
<li><a title="Gecko SDK documentation for NPN_ReleaseVariantValue" href="https://developer.mozilla.org/en/NPN_ReleaseVariantValue">NPN_ReleaseVariantValue</a> &#8211; Frees the value in a variant; if the VariantType is NPVariantType_String, calls NPN_MemFree; if it&#8217;s NPVariantType_Object, calls NPN_ReleaseObject</li>
</ul>
<p>Many may wonder, like I did, why we would need to call browser APIs to allocate and free memory, when malloc and free are standard on all C compilers.  The reason is that on many platforms (windows included) each DLL or EXE could have its own memory management routines and its own heap.  Thus if you allocate memory in your plugin DLL and then the browser frees it, or vise versa, you have a problem.</p>
<p>Now, remember our rule of thumb: if it&#8217;s returned as a return value, it will be released by the caller using the browser APIs.  When you need to return a string, you allocate it using NPN_MemAlloc, as in the following code snippet from FireBreath:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// We have:</span>
<span style="color: #666666;">// std::string str as the string to store</span>
<span style="color: #666666;">// NPVariant *dst as the destination NPVariant</span>
<span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>outStr <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>this<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>MemAlloc<span style="color: #008000;">&#40;</span>str.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000dd;">memcpy</span><span style="color: #008000;">&#40;</span>outStr, str.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, str.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
dst<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>type <span style="color: #000080;">=</span> NPVariantType_String<span style="color: #008080;">;</span>
dst<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>value.<span style="color: #007788;">stringValue</span>.<span style="color: #007788;">utf8characters</span> <span style="color: #000080;">=</span> outStr<span style="color: #008080;">;</span>
dst<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>value.<span style="color: #007788;">stringValue</span>.<span style="color: #007788;">utf8length</span> <span style="color: #000080;">=</span> str.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>Then when the browser (triggered by javascript) calls NPN_Invoke, and we use that method to store a NPString in the final parameter (NPVariant *result), the browser will be able to release the memory when it&#8217;s done with it.  Similarly, if you call NPN_Invoke, you need to call NPN_ReleaseVariantValue on the returned NPVariant when you&#8217;re done.  Also, you are responsible for both creating and releasing the NPVariant array that you pass into NPN_Invoke as arguments.  The same holds true for the NPVariant used in NPN_SetProperty.</p>
<p>The only time you are not responsible for freeing memory is when it is passed in such a way that you don&#8217;t have control of it when your function closes.  Similarly, if you have data that is still available after the function that created it is gone, you need to release it.</p>
<h1>Conclusion</h1>
<p>Well, the biggest thing that I can conclude from this is that I&#8217;m not yet capable of keeping things short.  My hope is that this may help someone; I&#8217;ve found links to my NPAPI blog posts in a lot of surprising places.  If you know another documentation site that should have a link to this post, please link it!  Also, if you know of another site that explains or illustrates things that need to be clarified from these posts, please post them in the comments!  The primary goal of this blog is to help link together and clarify information that is difficult to find for those getting started in new areas.</p>
<p>Thanks to all who read!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/12/memory-management-in-npapi/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Firebreath ready for testing</title>
		<link>http://colonelpanic.net/2009/12/firebreath-ready-for-testing/</link>
		<comments>http://colonelpanic.net/2009/12/firebreath-ready-for-testing/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 07:24:11 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=105</guid>
		<description><![CDATA[While I'm not ready to release a "beta" version of Firebreath yet, we are getting really close.  In fact, it's close enough that anyone feeling a little adventuresome shouldn't have any trouble setting up a test plugin and testing the limits.  We only support Windows so far (sorry guys, it's the platform I know best, and it's the one my client needed first), but we support both Internet Explorer and NPAPI (Firefox, probably Chrome and Safari as well).

A brief list of supported features:]]></description>
			<content:encoded><![CDATA[<h1>The Firebreath project</h1>
<p>Update: <a href="http://colonelpanic.net/2010/09/a-year-in-the-life-of-a-plugin-project/">See what is happening with FireBreath a year later</a></p>
<p>It&#8217;s been awhile since my last post!  Rest assured, that isn&#8217;t because I have lost interest, or because there was nothing to write about; rather, I was occupied with what I considered to be more important things.  If you&#8217;re reading this, you likely have already read my previous post, &#8220;<a title="Call for Plugin Developers" href="http://colonelpanic.net/2009/09/call-for-plugin-developers/" target="_blank">Call for plugin Developers</a>.&#8221;  If you haven&#8217;t, you might want to glance over it so that you know what I&#8217;m talking about =]</p>
<p>Firebreath has been sponsored by PacketPass, Inc.  I don&#8217;t have a web address for them, but I&#8217;ll post one later if they want me to do so.  The good news about that is that it means that unlike the vast majority of new open source projects, development of Firebreath is not going to halt before there is at least some sort of a usable project.</p>
<h1><span id="more-105"></span>Who is working on it?</h1>
<p>As you might guess, despite a lot of readers and comments on my last post, relatively few people have joined our mailing list and started helping.  I want to make particular mention of Georg Fritzsche of Germany who has been invaluable to me as a sounding board, as well as come up with some really cool ideas for improving Firebreath even more.  Aside from Georg, there are several others (Don, Jarom, Ben, &#8230; ya&#8217;ll know who you are) on the mailing list who have been a bit quieter, but nonetheless have been assisting with the brainstorming, planning, and in some small ways development of the project.  This may not sound like a lot, but for a special interest project such as this, I think it&#8217;s pretty good.  Of course, we can always use more help =]</p>
<h1>Where we&#8217;re at:</h1>
<p>While I&#8217;m not ready to release a &#8220;beta&#8221; version of Firebreath yet, we are getting really close.  In fact, it&#8217;s close enough that anyone feeling a little adventuresome shouldn&#8217;t have any trouble setting up a test plugin and testing the limits.  We only support Windows so far (sorry guys, it&#8217;s the platform I know best, and it&#8217;s the one my client needed first), but we support both Internet Explorer and NPAPI (Firefox, probably Chrome and Safari as well).</p>
<p>A brief list of supported features:</p>
<ul>
<li>NPAPI (Firefox, Chrome, Safari) support</li>
<li>ActiveX/IE support</li>
<li>Unified scripting API (define your objects for javascript use in one place, they work on all browsers)</li>
<li>Easy manipulation of the DOM</li>
<li>Event firing from the plugin into Javascript</li>
<li>System event handling (mouse events wired, keyboard events can be easily)</li>
<li>Basic framework for getting the HWND so you can do your drawing (needs to be fleshed out, but usable)</li>
<li>Easy configuration of all plugin properties (such as Mime type, description, GUIDs, etc)</li>
</ul>
<h1>How to create a plugin with Firebreath</h1>
<p>If you want to play with it (and please, please, please play with it and tell us what you think), it&#8217;s not too hard to get started.  On <a title="Firebreath google code project" href="http://code.google.com/p/firebreath/">the firebreath google code page</a> we have <a title="Building Firebreath" href="http://code.google.com/p/firebreath/wiki/BuildingFireBreath">instructions on how to build it</a>, including downloading of the source.  You can find it here: <a title="Building Firebreath" href="http://code.google.com/p/firebreath/wiki/BuildingFireBreath">http://code.google.com/p/firebreath/wiki/BuildingFireBreath</a></p>
<h2>Basic steps to build:</h2>
<ul>
<li>Use Mercurial to download the source</li>
<li>Use CMake to generate the project for either VS2005 or VS2008 (prep2005.cmd or prep2008.cmd)</li>
<li>Open the generated solution file (build/Firebreath.sln) in Visual Studio and build it</li>
<li>Run regsvr32.exe on the generated .dll (build/bin/Debug/)</li>
<li>open build/projects/PluginTemplate/gen/FBControl.htm and play with it with firebug or jash</li>
</ul>
<h2>Basic steps to create your own Plugin:</h2>
<ul>
<li>Copy projects/PluginTemplate to projects/YourPlugin</li>
<li>Update pluginConfig.cmake &#8212; <em><strong>REPLACE ALL 6 GUIDs WITH YOUR OWN!</strong></em> &#8212; and set the mime type, plugin name, etc</li>
<li>Rename TemplatePlugin.cpp and .h however you want and update the files so that it is your plugin</li>
<li>Update factoryMain.cpp to create your plugin instead of TemplatePlugin</li>
<li>Update your &#8220;PluginCore&#8221; implementation (TemplatePlugin extends PluginCore) to return the correct API type by editing createJSAPI() and copying MathAPI.h and .cpp to whatever you like.</li>
<li>Update your JSAPI object (copied from MathAPI.h/.cpp) to have the methods, properties, and optionally events that you want</li>
<li>Update CMakeLists.txt to make sure it includes any files that you need</li>
<li>run prep200(?).cmd to regenerate the solution and project files</li>
<li>build your plugin, run regsvr32.exe on it, and use build/projects/YourPlugin/gen/FBControl.h for testing</li>
</ul>
<h1>How to get more involved</h1>
<p>We can use all the help we can get!  The porting effort to linux and mac shouldn&#8217;t be astronomical, but currently we have nobody to put on it at least until after 1.0 is out (RC1 planned for end of the year 2009, 1.0 planned for end of January, 2010).  There are a lot of little things that can be done by developers without a lot of plugin experience, as well as some real complex bugs and challenges that will require a bit more experience.</p>
<p>If you are interested in helping, even if just by making suggestions, asking questions, and making comments, please join the development list:</p>
<p><a title="Firebreath-dev maling list" href="http://groups.google.com/group/firebreath-dev">http://groups.google.com/group/firebreath-dev</a></p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/12/firebreath-ready-for-testing/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Call for plugin Developers</title>
		<link>http://colonelpanic.net/2009/09/call-for-plugin-developers/</link>
		<comments>http://colonelpanic.net/2009/09/call-for-plugin-developers/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 04:01:15 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[cross-platform]]></category>
		<category><![CDATA[firebreath]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=94</guid>
		<description><![CDATA[Call for help Update: See what is happening with FireBreath a year later I hereby issue a &#8220;Call for Plugin Developers&#8221; to the readers of the site. I know we are as of yet few, but I hope that some of you may be willing to help me. I am quickly realizing that I need a [...]]]></description>
			<content:encoded><![CDATA[<h2>Call for help</h2>
<p>Update: <a href="http://colonelpanic.net/2010/09/a-year-in-the-life-of-a-plugin-project/"><strong>See what is happening with FireBreath a year later</strong></a></p>
<p>I hereby issue a &#8220;Call for Plugin Developers&#8221; to the readers of the site.  I know we are as of yet few, but I hope that some of you may be willing to help me.</p>
<p>I am quickly realizing that I need a plugin project from which I can quote source code; one that does the things that I am attempting to explain, and one that is not made up of code that is owned  by a specific company or project.</p>
<p>Thus, I introduce to you all: <a href="http://code.google.com/p/firebreath/">FireBreath</a>.</p>
<h2>FireBreath</h2>
<p>FireBreath is intended to be a cross platform browser plugin.  Currently, I plant to license this under the new BSD license.  This way, it can be used for commercial projects.  The targetted browsers are:</p>
<p><span id="more-94"></span>On windows:</p>
<ul>
<li>Microsoft Internet Explorer</li>
<li>Mozilla Firefox (3 and up; we may add support for 2.x as well)</li>
<li>Google Chrome</li>
<li>Opera</li>
<li>Apple Safari</li>
</ul>
<p>On mac:</p>
<ul>
<li>Mozilla Firefox (see above note on versions)</li>
<li>Google Chrome (when it is released)</li>
<li>Apple Safari (3.x and up, intel only for now)</li>
</ul>
<p>On linux:</p>
<ul>
<li>Anything that supports NPAPI plugins and Gecko SDK 1.9 or above (no firefox 2 for now)</li>
</ul>
<h2>What needs to be done</h2>
<p>This is an ambitious project; I can help with development, and I can coordinate tasks.  I don&#8217;t have time to do it all myself, however, unless a company sponsers me; there is one that has shown interest so far, but nothing is certain.  Even if that happens, and a company wants this project enough to pay me to develop it, it will be far more successful if there are other contributors &#8212; you see, I don&#8217;t know everything.</p>
<p>In particular, I could really use a &#8220;strong right hand&#8221; who would be willing to head up the linux-specific part of the development, which despite 10+ years of linux experience is still my weakest point.  If there are others who wish to take ownership of other parts, that would also be great; for now, I will retain the final say on what goes in, because, well, I can.</p>
<p>If you look, you&#8217;ll find that there is no code up on the repository as of yet (at least, as of the time of this writing.)  I just started an ActiveX control this evening with the intent to implement FBControl, the ActiveX control portion of FireBreath.  As soon as I have a rough skeleton ActiveX control project done (which will happen sooner if I get a lot of developers wanting to help), I will start on the NPAPI portion of the DLL.  Even before I have that done, there are several small, relatively simple tasks that I could use help with.  In particular, I will not be using any code directly from the mozilla source tree and the plugin samples, so I need someone to write from scratch the NPN_ wrappers for all of the browser functions.</p>
<h2>How you can help</h2>
<p>For this project to succeed, we need all the help we can get.  If you would like to help, please send me an email at taxilian@gmail.com and introduce yourself.  Tell me:</p>
<ul>
<li>Who you are</li>
<li>What you consider your strengths in this area are</li>
<li>What interests you most about this project</li>
<li>How you want to use FireBreath yourself (if at all)</li>
<li>How much time you may be able to put in</li>
</ul>
<p>I&#8217;ll take nearly anyone right now, though I will be carefully monitoring the code submissions to start out with; my project goals are:</p>
<ul>
<li>Reusable and modular</li>
<li>Cross-platform (both in the browser sense and the operating system sense)</li>
<li>Cleanly written</li>
<li>Free and useful</li>
</ul>
<p>I by no means want to be a dictator on this; I welcome help and suggestions from everyone.</p>
<p>Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/09/call-for-plugin-developers/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>Building a firefox plugin – part three</title>
		<link>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/</link>
		<comments>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 05:20:46 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[npobject]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[npvariant]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=72</guid>
		<description><![CDATA[Note: For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the FireBreath project. Getting help: For a better place to ask NPAPI-related questions, check out the FireBreath Forums. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well. Previous [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: </strong>For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the <a href="http://www.firebreath.org">FireBreath project</a>.</p>
<p><strong>Getting help: </strong>For a better place to ask NPAPI-related questions, check out the <a href="http://forum.firebreath.org">FireBreath Forums</a>. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well.</p>
<h2>Previous posts</h2>
<p>The purpose of this post is to cover the basics of providing an interface by which javascript can interface with an NPAPI plugin in a cross platform manner.  The primary focus of this post will be on <a title="Mozilla Plugin API Reference : Scripting Plugins" href="https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins" target="_blank">npruntime</a>, which is recommended by the Mozilla development team (or at least seems to be from the <a title="Mozilla Plugin API Reference" href="https://developer.mozilla.org/En/plugins">meager and confusing documentation</a> available from Mozilla).  More importantly, of course, it is the framework that I recommend, which is all-important, since I&#8217;m the one writing this post. =]</p>
<h2><span id="more-72"></span>Previous posts</h2>
<p>If you are new to NPAPI plugins, you may want to go back and read <a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/" target="_blank">part one</a> and <a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">part two</a> of this series, which cover the basic architecture and lifecycle of an NPAPI plugin.</p>
<h2>What is npruntime?</h2>
<p>I&#8217;m so glad you ask.  This confused the daylights out of me when I first got into building browser plugins; there are references to XPCOM and references to LiveConnect and references to NPRuntime, which I never did quite get straightened out until I ran into <a title="Netscape Plugin Application Programming Interface" href="http://en.wikipedia.org/wiki/Netscape_Plugin_Application_Programming_Interface" target="_blank">a Wikipedia article on NPAPI</a>.  I recommend that you read it if you want further background information.</p>
<p>Beyond the simple question of &#8220;what is recommended?&#8221; is the consideration of practical needs.  For me, the primary considerations that led me to decide that NPRuntimeis the only mechanism that should be used on any new plugin are:</p>
<ul>
<li>NPRuntime allows dynamic interfaces &#8212; more on this, and why it is useful, later</li>
<li>NPRuntime is the plugin scripting standard supported by Mac Plugins, Safari (even on windows), Chrome, and Opera.  My goal is always to make things as cross-platform as possible.</li>
<li>Firefox 3.6 drops support for XPCOM plugins (e.g. xpt file scripting interfaces aren&#8217;t recognized)</li>
</ul>
<h2>Getting Started</h2>
<p>Throughout this post, I will be referring to Scriptable Objects a lot.  A Scriptable Object is simply an object that can be &#8220;scripted&#8221;, or accessed and used by javascript.  In firefox, a Scriptable Object is always a <a title="NPObject - MDC" href="https://developer.mozilla.org/en/NPObject" target="_blank">NPObject</a>:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> NPObject <span style="color: #008000;">&#123;</span>
  NPClass <span style="color: #000040;">*</span>_class<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">uint32_t</span> referenceCount<span style="color: #008080;">;</span>
  <span style="color: #ff0000; font-style: italic;">/*
   * Additional space may be allocated here by types of NPObjects
   */</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>As you can see, a NPObject is nothing more than a reference counted object with a pointer to a <a title="NPClass - MDC" href="https://developer.mozilla.org/en/NPClass">NPClass</a>.  As of the latest (as of this writing) Gecko SDK, 1.9, NPClass is defined as follows:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> NPClass
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">uint32_t</span> structVersion<span style="color: #008080;">;</span> <span style="color: #666666;">// Version of the structure (to determine which features may be missing)</span>
  NPAllocateFunctionPtr allocate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to create a new instance of this object</span>
  NPDeallocateFunctionPtr deallocate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to free the instance of this object</span>
  NPInvalidateFunctionPtr invalidate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called on live objects that belong to a plugin instance that is being destroyed. This call is always followed by a call to the &lt;code&gt;deallocate&lt;/code&gt; function, or &lt;code&gt;free()&lt;/code&gt;. Any attempt to use an invalidated object will result in undefined behavior.</span>
  NPHasMethodFunctionPtr hasMethod<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to query if a method exists on the NPObject</span>
  NPInvokeFunctionPtr invoke<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to invoke a method on the NPObject</span>
  NPInvokeDefaultFunctionPtr invokeDefault<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to invoke the NPObject as a function</span>
  NPHasPropertyFunctionPtr hasProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to query if a property exists on the NPObject</span>
  NPGetPropertyFunctionPtr getProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to get the value of a property on the NPObject</span>
  NPSetPropertyFunctionPtr setProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to set the value of a property on the NPObject</span>
  NPRemovePropertyFunctionPtr removeProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to remove/delete a property on the NPObject</span>
  NPEnumerationFunctionPtr enumerate<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to get a list of properties and methods that exist on the NPObject (new in FF 3, Gecko SDK 1.9)</span>
  NPConstructFunctionPtr construct<span style="color: #008080;">;</span> <span style="color: #666666;">// Used when the new keyword is called in javascript to create a new instance of the NPObject (new in FF 3, Gecko SDK 1.9)</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Making it Object Oriented</h2>
<p>The Gecko SDK is intentionally written to use structs instead of objects; this allows it to work across many platforms, with many different types of compilers, and never worry about binary compatibility.  If you haven&#8217;t figured it out yet, the NPClass structure contains a list of function pointers that should be called by the browser (or anyone else) to talk to the NPObject.  These should never be called explicitly, but rather they should be called through the NPN_ functions that I briefly mentioned towards the end of <a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/" target="_blank">part one</a>.  When one wishes to create a new instance of an NPObject, you call the <a title="NPN_CreateObject - MDC" href="https://developer.mozilla.org/en/NPN_CreateObject">NPN_CreateObject</a> function and give it the class that should be used.</p>
<p>Fortunately, since all the browser cares about is the NPClass, its function pointers, and the reference count, any class that inherits from NPObject can easily satisfy that requirement; that means that it is not difficult to make a smart NPObject; simply create static methods for each of the pointers in the NPClass struct, dereference the NPObject* that they pass in, and call a member function.</p>
<h2>Simple class definition and implementation:</h2>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &quot;npapi.h&quot;</span>
<span style="color: #339900;">#include &quot;npupp.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">class</span> MyScriptableNPObject <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> NPObject
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// Class member functions that do the real work</span>
    <span style="color: #0000ff;">void</span> Deallocate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">void</span> Invalidate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> HasMethod<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Invoke<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> InvokeDefault<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> HasProperty<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> GetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> SetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> RemoveProperty<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Enumerate<span style="color: #008000;">&#40;</span>NPIdentifier <span style="color: #000040;">**</span>identifier, <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span>count<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Construct<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// This is the method used to create the NPObject</span>
    <span style="color: #666666;">// This method should not be called explicitly</span>
    <span style="color: #666666;">// Instead, use NPN_CreateObject</span>
    <span style="color: #0000ff;">static</span> NPObject<span style="color: #000040;">*</span> Allocate<span style="color: #008000;">&#40;</span>NPP npp, NPClass <span style="color: #000040;">*</span>aClass<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">new</span> MyScriptableNPObject<span style="color: #008000;">&#40;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #666666;">/////////////////////////////</span>
    <span style="color: #666666;">// Static NPObject methods //</span>
    <span style="color: #666666;">/////////////////////////////</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> _Deallocate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> _Invalidate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _HasMethod<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Invoke<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _InvokeDefault<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _HasProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span> npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _GetProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _SetProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _RemoveProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Enumerate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier <span style="color: #000040;">**</span>identifier, <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span>count<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Construct<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">static</span> NPClass _npclass<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    NPP m_Instance<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>Due to code ownership issues, I&#8217;m not able to give you the actual code that I&#8217;m using, but if there are any compiler errors I&#8217;m sure they&#8217;ll be simple to straighten out.  The implementation for these static members will be pretty straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// static</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span>_Invalidate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>obj<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Invalidate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Invalidate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Invalidate the control however you wish</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #666666;">// static</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span>_Deallocate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>obj<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Deallocate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Deallocate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Do any cleanup needed</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>For brevity, I&#8217;m not going to include all of the methods here; I will go into more detail on them later.  For now, suffice it to say that after you have implemented the rest of these functions, all that is left is to define the NPClass itself:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPClass MyScriptableNPObject<span style="color: #008080;">::</span>_npclass <span style="color: #000080;">=</span> <span style="color: #008000;">&#123;</span>
    NP_CLASS_STRUCT_VERSION,
    MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Allocate</span>,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Deallocate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Invalidate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_HasMethod,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Invoke,
    MyScriptableNPObject<span style="color: #008080;">::</span>_InvokeDefault,
    MyScriptableNPObject<span style="color: #008080;">::</span>_HasProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_GetProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_SetProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_RemoveProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Enumerate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Construct
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Creating the NPObject</h2>
<p>Once you have your custom NPObject created and your NPClass defined, we can cover the basics of the NPObject lifecycle.  Creating an NPObject is pretty straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPObject <span style="color: #000040;">*</span>newObj <span style="color: #000080;">=</span> NPN_CreateObject<span style="color: #008000;">&#40;</span>m_Instance, <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>MyScriptableNPObject<span style="color: #008080;">::</span>_npclass<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
NPN_RetainObject<span style="color: #008000;">&#40;</span>newObj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>As you can see, all that is needed is the NPP instance handler (see <a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">part two</a>) and a pointer to the class.  Since the class is very specific to a specific NPObject, I like to create a static function to instantiate the object, like so:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">static</span> MyScriptableNPObject<span style="color: #000040;">*</span> NewObject<span style="color: #008000;">&#40;</span>NPP npp<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    MyScriptableNPObject<span style="color: #000040;">*</span> newObj <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>NPN_CreateObject<span style="color: #008000;">&#40;</span>npp, <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>_npclass<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> newObj<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>This is completely voluntary, of course, but it also allows you some additional control of the creation process; for example, you may want to pass in additional parameters and have them set on the object as soon as it is created.</p>
<h2>NPObject lifecycle</h2>
<p>As you might guess, <a title="NPN_RetainObject - MDC" href="https://developer.mozilla.org/En/NPN_RetainObject">NPN_RetainObject </a>increments the reference count on a given NPObject.  Similarly, <a title="NPN_ReleaseObject - MDC" href="https://developer.mozilla.org/En/NPN_ReleaseObject" target="_blank">NPN_ReleaseObject </a>decrements the reference count.  When the reference count hits zero, the object will be destroyed by calling the specified Deallocate function, just like the Allocate function is called by NPN_CreateObject to create the object.</p>
<p>When code in one DLL allocates something and it is deallocated by a different DLL, heap corruption can (and often does) occur.  For this reason, all things that belong to you will ultimately get created and destroyed in your code.  All things that belong to the browser will get created and freed in browser code.  This way everyone stays happy =]  Make sure you keep track of your Retains and Releases; just like any reference counting, this can cause you a lot of hard to track problems.</p>
<p>Another important thing to keep in mind about the lifecycle of a NPObject is that you don&#8217;t know exactly when it will go away; the browser will release it whenever it chooses to do so.  Therefore, you need to be able to handle things gracefully even if things are destroyed in a different order than you expect.</p>
<h2>Giving the correct NPObject to the browser</h2>
<p>Now that you know what an NPObject is and rougly what it does, you need to know how the browser finds out about it.  If you&#8217;ll refer back to <a title="Building a firefox plugin - part two" href="../2009/05/building-a-firefox-plugin-part-two/">part two</a> and look at the plugin lifecycle, you&#8217;ll see on entry #5 that &#8220;Plugin creates a scriptable NPObject and returns a pointer to it (after calling <a title="NPN_RetainObject SDK docs" href="https://developer.mozilla.org/En/NPN_RetainObject" target="_blank">NPN_RetainObject</a> on it.)&#8221;  Simply put, at that point in the initialization sequence (or somewhere in there; the spec is ambiguous about the order), the Browser will call GetValue on the plugin and ask for a NPObject.  If our plugin supports NPObjects, it simply needs to create one, call <a title="NPN_RetainObject SDK docs" href="https://developer.mozilla.org/En/NPN_RetainObject" target="_blank">NPN_RetainObject</a> on it, and return it as a void pointer.  <strong>*NOTE: Make sure that you typecast it as a NPObject* before assigning it to the void pointer; I made that mistake once and spent a week trying to figure out why the wrong functions were getting called.</strong></p>
<p>Here is an example implementation of GetValue:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPError PluginInstance<span style="color: #008080;">::</span><span style="color: #007788;">NpapiGetValue</span><span style="color: #008000;">&#40;</span>NPPVariable variable, <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   NPError rv <span style="color: #000080;">=</span> NPERR_NO_ERROR<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>variable<span style="color: #008000;">&#41;</span>
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginNameString<span style="color: #008080;">:</span>
          value <span style="color: #000080;">=</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> STRINGS_PRODUCTNAME<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginDescriptionString<span style="color: #008080;">:</span>    <span style="color: #666666;">// Plugin description</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> STRINGS_FILEDESCRIPTION<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginScriptableNPObject<span style="color: #008080;">:</span><span style="color: #666666;">// Scriptable plugin interface (for accessing from javascript)</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value <span style="color: #000080;">=</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getScriptableObject<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginWindowBool<span style="color: #008080;">:</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>PRBool <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>isWindowed<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">default</span><span style="color: #008080;">:</span>
          rv <span style="color: #000080;">=</span> NPERR_GENERIC_ERROR<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">return</span> rv<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
NPObject <span style="color: #000040;">*</span>PluginInstance<span style="color: #008080;">::</span><span style="color: #007788;">getScriptableObject</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   NPObject <span style="color: #000040;">*</span>retval<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npobj <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
      retval <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npobj<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">else</span>
      retval <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">NewObject</span><span style="color: #008000;">&#40;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   NPN_RetainObject<span style="color: #008000;">&#40;</span>retval<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #0000ff;">return</span> retval<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<h2>HasMethod and HasProperty</h2>
<p>On to the meat of the article: Say you have a javascript function like so:</p>
<pre>var objTag = document.getElementById("myObjectTag");
alert(objTag.doSomeCoolFunction);</pre>
<p>You may think that this looks a little strange, since &#8220;doSomeCoolFunction&#8221; sounds like a function call, but it is clearly accessed like a parameter here.  In Javascript, this is legal even if that is a function, because it can be used to determine if a function exists without calling it.  Therefore, you cannot have a method and a property on the same object with the same name.</p>
<p>When this call is made, the browser will call two functions on the NPObject:</p>
<ol>
<li><a title="NPN_HasMethod - MDC" href="https://developer.mozilla.org/en/NPN_HasMethod" target="_blank">HasMethod</a>(NPIdentifier name);</li>
<li><a title="NPN_HasProperty - MDC" href="https://developer.mozilla.org/en/NPN_HasProperty" target="_blank">HasProperty</a>(NPIdentifier name);</li>
</ol>
<p>The purpose of these two calls is to ascertain whether or not a property or method exists on the NPObject (as you might have guessed).  So, what is with this <a title="NPIdentifier - MDC" href="https://developer.mozilla.org/en/NPIdentifier" target="_blank">NPIdentifier </a>thing?  Well, a NPIdentifier can map to either an integer or a string.  a NPIdentifier can be converted to a string (if it is a string identifier) with <a title="NPN_UTF8FromIdentifier - MDC" href="https://developer.mozilla.org/en/NPN_UTF8FromIdentifier" target="_blank">NPN_UTF8FromIdentifier</a>.  To find out if it is a string identifier, use <a href="https://developer.mozilla.org/en/NPN_IdentifierIsString" target="_blank href=">NPN_IdentifierIsString</a>.  If it is an integer, you can use <a href="https://developer.mozilla.org/en/NPN_IntFromIdentifier" rel="custom nofollow" target="_blank">NPN_IntFromIdentifier</a>.</p>
<p>Now, the purpose of integer identifiers may not be immediately apparent to everyone; it wasn&#8217;t to me at first.  Once I figured it out, however, I was thrilled.  If you are familiar with javascript, you are doubtlessly familiar with the concept that everything in javascript is an object; arrays are actually just objects with integer keys.  So, to allow array-style access, simply handle integer identifiers!</p>
<p>Once you have converted the identifier into something you can deal with, decide if your object has that property or method (I&#8217;ll let you figure out which goes in which function) and return true or false.</p>
<p>Oh, and after you get a string wtih NPN_UTF8FromIdentifier, don&#8217;t forget to release the memory with <a href="https://developer.mozilla.org/en/NPN_MemFree" rel="internal">NPN_MemFree()</a>.</p>
<h2>NPVariant</h2>
<p>Before I go any further, I need to spend a brief paragraph or two on the <a title="NPVariant structure documentation" href="https://developer.mozilla.org/en/NPVariant" target="_blank">NPVariant structure</a>.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPVariant <span style="color: #008000;">&#123;</span>
  NPVariantType type<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">union</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> boolValue<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int32_t</span> intValue<span style="color: #008080;">;</span>
    double_t doubleValue<span style="color: #008080;">;</span>
    NPString stringValue<span style="color: #008080;">;</span>
    NPObject <span style="color: #000040;">*</span>objectValue<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span> value<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> NPVariant<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>NPVariant is the datatype used by the browser to pass variables into and out of NPObjects.  From the MDC docs, the following types are valid:</p>
<table border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<th>JavaScript type</th>
<th><code>NPVariantType</code></th>
</tr>
<tr>
<td><code>undefined</code></td>
<td><code>NPVariantType_Void</code></td>
</tr>
<tr>
<td><code>null</code></td>
<td><code>NPVariantType_Null</code></td>
</tr>
<tr>
<td><code>boolean</code></td>
<td><code>NPVariantType_Bool</code></td>
</tr>
<tr>
<td><code>number</code></td>
<td><code>NPVariantType_Int32</code> or <code>NPVariantType_Double</code></td>
</tr>
<tr>
<td><code>string</code></td>
<td><code>NPVariantType_String</code></td>
</tr>
<tr>
<td>All other types</td>
<td><code>NPVariantType_Object</code></td>
</tr>
</tbody>
</table>
<p>Since it&#8217;s getting late and I&#8217;ve already put too much in this post (I&#8217;m over 2000 words), I&#8217;ll leave it as an excercise to the reader to <a title="NPVariant docs" href="https://developer.mozilla.org/en/NPVariant" target="_blank">read up on the macros and such for using this structure</a>.</p>
<h2>Properties</h2>
<p>At this point, you should be getting a pretty good idea of how everything works.  Getting and setting properties is fairly straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">bool</span> GetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> SetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>To get a property, simply check the name to see what you&#8217;re going to be doing and store the value to return in *result.  If the operation succeeds, you should return true.  If not, false.</p>
<p>To set a property, again check the name to see which property you&#8217;re working with and save the value of the NPVariant parameter however you wish.  Again, return true if success, false if failure.</p>
<h2>Methods</h2>
<p>Methods aren&#8217;t much more difficult.  The only real difference is that now you have parameters to worry about.  No problem!  Parameters are passed in as an array of NPVariants:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">bool</span> Invoke<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> InvokeDefault<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>The difference between Invoke and InvokeDefault is that InvokeDefault does not ever have an identifier.  If you call &#8220;objTag.funcName()&#8221; Invoke gets called; if you call &#8220;objTag()&#8221;, then InvokeDefault gets called.</p>
<p>As with properties, store the return value in the pointer given in the last argument and handle the other arguments however you wish.</p>
<h2>Wrapping it up</h2>
<p>Alright, I know I haven&#8217;t covered everything, but this is already too long.  If you have specific questions, ask them in the comments and I&#8217;ll do my best to answer; the comments may determine the direction of my next post.</p>
<p>Since dealing with the NPIdentifiers can get to be such a pain, I recommend using a map or hashtable to store structures with function pointers to map a string name to functions to handle it; that way you don&#8217;t end up with giant if/then or case statements, and everything ends up being much cleaner.</p>
<p>Another idea for the adventuresome: abstract the actual logic (properties and methods) into another object that can be wrapped with your NPObject class, and then make another wrapper class that implements <a title="MSDN: IDispatch" href="http://msdn.microsoft.com/en-us/library/ms221608.aspx" target="_blank">IDispatch </a>so that your scriptable objects are cross platform (IDispatch objects are scriptable on Internet Explorer).</p>
<p>Good luck!</p>
<p><a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/">Building a firefox plugin &#8211; part one</a></p>
<p><a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">Building a firefox plugin &#8211; part two</a></p>
<p><a title="Building a firefox plugin - part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/">Building a firefox plugin &#8211; part three</a></p>
<p><a title="Building a firefox plugin - part four" href="http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/">Building a firefox plugin &#8211; part four</a></p>
<h2>Getting more help</h2>
<p><strong>Update May 14, 2011:</strong> Many people have been asking questions in the comments; while I don&#8217;t mind that, it would probably be more useful if you ask your question on <a href="http://forum.firebreath.org">the FireBreath forums</a>. There is a forum there for those just using NPAPI as well!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/feed/</wfw:commentRss>
		<slash:comments>200</slash:comments>
		</item>
		<item>
		<title>Building a firefox plugin – part two</title>
		<link>http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/</link>
		<comments>http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/#comments</comments>
		<pubDate>Wed, 27 May 2009 00:07:34 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[lifecycle]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=49</guid>
		<description><![CDATA[Note: For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the FireBreath project. Getting help: For a better place to ask NPAPI-related questions, check out the FireBreath Forums. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well. Recap [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: </strong>For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the <a href="http://www.firebreath.org">FireBreath project</a>.</p>
<p><strong>Getting help: </strong>For a better place to ask NPAPI-related questions, check out the <a href="http://forum.firebreath.org">FireBreath Forums</a>. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well.</p>
<h3>Recap</h3>
<p><a title="Buliidng a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/" target="_blank">Last time</a>, I talked about the fundamentals of implementing a NPAPI plugin.  Today, I&#8217;m going to go into a little more detail on how to use the strange callback architecture that firefox exposes.</p>
<p>The NPAPI uses a rather unique (in my experience) methodology for providing an interface between the plugin and browser, but it does have some rather significant advantages.  Instead of providing binaries to be linked against, the browser simply expects you to implement the entry point <a title="Gecko NPAPI reference: NP_Initialize" href="https://developer.mozilla.org/En/NP_Initialize">NP_Initialize</a> in your dll that the browser will call and tell you where the methods that <span id="more-49"></span>you will be using are located.  In order for the browser to interface with you, it calls <a title="Gecko API reference" href="https://developer.mozilla.org/Talk:En/Gecko_Plugin_API_Reference/Plug-in_Side_Plug-in_API">NP_GetEntryPoints</a> with a pointer to a structure for your plugin to fill out with function pointers that the browser will be calling on your plugin.</p>
<p>This removes the need for a large number of include and library files in your project. <span style="text-decoration: line-through;"> In fact, in practice I found that I only actually needed 12 include files from the <a title="Gecko SDK" href="https://developer.mozilla.org/En/Gecko_SDK" target="_blank">Gecko SDK</a>:</span></p>
<ul>
<li><span style="text-decoration: line-through;">jni.h</span></li>
<li><span style="text-decoration: line-through;">jni_md.h</span></li>
<li><span style="text-decoration: line-through;">jri.h</span></li>
<li><span style="text-decoration: line-through;">jritypes.h</span></li>
<li><span style="text-decoration: line-through;">jri_md.h</span></li>
<li><span style="text-decoration: line-through;">npapi.h</span></li>
<li><span style="text-decoration: line-through;">npruntime.h</span></li>
<li><span style="text-decoration: line-through;">nptypes.h</span></li>
<li><span style="text-decoration: line-through;">npupp.h</span></li>
<li><span style="text-decoration: line-through;">obsolete/protypes.h</span></li>
<li><span style="text-decoration: line-through;">prcpucfg.h</span></li>
<li><span style="text-decoration: line-through;">prtypes.h</span></li>
</ul>
<p><strong>Edit (Sep 16, 2010):</strong> Now over a year later there is a better way to do this.  There is a Google Code project called <a title="npapi-headers project" href="http://code.google.com/p/npapi-headers/" target="_blank">npapi-headers</a> that has just the header files you need &#8212; and they actually work on all browsers, all platforms (unlike the ones from the gecko SDK sometimes).</p>
<h3>Basic Lifecycle of a plugin:</h3>
<p><strong></strong>Jean-Lou Dupont has an excelent visual diagram of this on his blog, which you can find here: <a title="Notes on NPAPI-based plugins" href="http://jldupont.blogspot.com/2009/11/notes-on-npapi-based-plugins.html">http://jldupont.blogspot.com/2009/11/notes-on-npapi-based-plugins.html</a></p>
<p>The lifecycle of a plugin is actually pretty simple, once you figure it out.  The initial entrypoints <a title="Gecko NPAPI reference: NP_Initialize" href="https://developer.mozilla.org/En/NP_Initialize">NP_Initialize</a> and <a title="Gecko API reference" href="https://developer.mozilla.org/Talk:En/Gecko_Plugin_API_Reference/Plug-in_Side_Plug-in_API">NP_GetEntryPoints</a> could, according to the documentation, get called in any order; however, in practice, <a title="Gecko API reference" href="https://developer.mozilla.org/Talk:En/Gecko_Plugin_API_Reference/Plug-in_Side_Plug-in_API">NP_GetEntryPoints</a> seems to get called first on Windows.  With that in mind, here is the order of calls for basic windowed plugin initialization on Windows:</p>
<ol>
<li><a title="Gecko API reference" href="https://developer.mozilla.org/Talk:En/Gecko_Plugin_API_Reference/Plug-in_Side_Plug-in_API">NP_GetEntryPoints</a> &#8211; Plugin fills out a function table with the addresses of <a title="NPP_New API doc" href="https://developer.mozilla.org/En/NPP_New" target="_blank"><tt><span>NPP_New</span></tt></a>, <a title="NPP_Destroy API doc" href="https://developer.mozilla.org/En/NPP_Destroy" target="_blank"><tt><span>NPP_Destroy</span></tt></a>, <a title="NPP_SetWindow API doc" href="https://developer.mozilla.org/En/NPP_SetWindow" target="_blank"><tt><span>NPP_SetWindow</span></tt></a>, etc</li>
<li><a title="Gecko NPAPI reference: NP_Initialize" href="https://developer.mozilla.org/En/NP_Initialize">NP_Initialize</a> &#8211; Plugin stores a copy of a function table with the addresses of <a title="NPN_CreateObject sdk documentation" href="https://developer.mozilla.org/En/NPN_CreateObject" target="_blank">NPN_CreateObject</a>, <a title="NPN_MemAlloc SDK docs" href="https://developer.mozilla.org/En/NPN_MemAlloc">NPN_MemAlloc</a>, etc</li>
<li><a title="NPP_New API doc" href="https://developer.mozilla.org/En/NPP_New" target="_blank">NPP_New</a> &#8211; Plugin creates a new instance of itself and initializes it</li>
<li>*<a title="NPP_SetWindow API doc" href="https://developer.mozilla.org/En/NPP_SetWindow" target="_blank">NPP_SetWindow</a> &#8211; This is called multiple times for each instance &#8212; each time the instance&#8217;s window is created, resized, or otherwise changed</li>
<li><a title="NPP_GetValue API doc" href="https://developer.mozilla.org/En/NPP_GetValue" target="_blank">NPP_GetValue</a> (Variable = NPPVpluginScriptableNPObject) &#8211; Plugin creates a scriptable NPObject and returns a pointer to it (after calling <a title="NPN_RetainObject SDK docs" href="https://developer.mozilla.org/En/NPN_RetainObject" target="_blank">NPN_RetainObject</a> on it)</li>
<li>&#8212; Standard Plugin Activity &#8212;</li>
<li><a title="NPP_Destroy sdk docs" href="https://developer.mozilla.org/En/NPP_Destroy">NPP_Destroy</a> &#8211; Plugin instance is destroyed</li>
<li><a title="NP_Shutdown SDK docs" href="https://developer.mozilla.org/En/NP_Shutdown">NP_Shutdown</a> &#8211; All remaining plugin resources are destroyed</li>
</ol>
<p>It is worth our time to investigate a few of these calls in more detail.</p>
<h3><span style="font-size: medium;"><span>NPError NPP_New(NPMIMEType pluginType, NPP npp, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved)</span></span></h3>
<div><a title="NPP_New API doc" href="https://developer.mozilla.org/En/NPP_New" target="_blank">NPP_New</a> is called once for each <em>instance </em>of the plugin.  Note the difference in terminology: There is one <em>plugin</em>, and there are multiple <em>instances </em>of that plugin.  NP_Initialize is only called once for the <em>plugin </em>&#8211; that is, the entire memory space.</div>
<div>From the Gecko SDK source:</div>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #ff0000; font-style: italic;">/*
 *  NPP is a plug-in's opaque instance handle
 */</span>
<span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPP
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">void</span><span style="color: #000040;">*</span>pdata<span style="color: #008080;">;</span>      <span style="color: #ff0000; font-style: italic;">/* plug-in private data */</span>
  <span style="color: #0000ff;">void</span><span style="color: #000040;">*</span>ndata<span style="color: #008080;">;</span>      <span style="color: #ff0000; font-style: italic;">/* netscape private data */</span>
<span style="color: #008000;">&#125;</span> NPP_t<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">typedef</span> NPP_t<span style="color: #000040;">*</span>  NPP<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>This structure is normally seen as NPP and serves as the handle of a plugin instance. As you can see, there is private data for the plugin and private data for the browser.  When <a title="NPP_New API doc" href="https://developer.mozilla.org/En/NPP_New" target="_blank">NPP_New</a> is called, you should:</p>
<ol>
<li>Create some sort of data structure to uniquely identify this instance of the plugin</li>
<li>Assign a pointer to that data structure to npp-&gt;pdata</li>
</ol>
<p>What I like to do is to create a PluginInstance class and use that as my &#8220;pdata&#8221;.  Then my NPP_New function looks like this:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Called by the browser to create a new instance of the plugin</span>
&nbsp;
NPError NPP_New<span style="color: #008000;">&#40;</span>NPMIMEType pluginType,
            NPP npp,
            <span style="color: #0000ff;">uint16</span> mode,
            <span style="color: #0000ff;">int16</span> argc,
            <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> argn<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span>,
            <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span>,
            NPSavedData<span style="color: #000040;">*</span> saved<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>npp <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> NPERR_INVALID_INSTANCE_ERROR<span style="color: #008080;">;</span>
&nbsp;
    NPError rv <span style="color: #000080;">=</span> NPERR_NO_ERROR<span style="color: #008080;">;</span>
    PluginInstance<span style="color: #000040;">*</span> pPluginObj <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> PluginInstance<span style="color: #008000;">&#40;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>pPluginObj <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> NPERR_OUT_OF_MEMORY_ERROR<span style="color: #008080;">;</span>
&nbsp;
    npp<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>pdata <span style="color: #000080;">=</span> pPluginObj<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> pPluginObj<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>NpapiNew<span style="color: #008000;">&#40;</span>pluginType, mode, argc, argn, argv, saved<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>In this way I can have a PluginInstance class that handles the entire lifecycle of a given instance of a plugin, and I simply create stub static functions to dereference the pdata pointer and call the correct function.</p>
<h3>NPP_SetWindow (NPP npp, NPWindow* pNPWindow)</h3>
<p>For many, this will be where the real fun starts &#8212; this function is called to tell the plugin which window they are in.  From the Gecko SDK (npapi.h):</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPWindow
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">void</span><span style="color: #000040;">*</span> window<span style="color: #008080;">;</span>  <span style="color: #ff0000; font-style: italic;">/* Platform specific window handle */</span>
                 <span style="color: #ff0000; font-style: italic;">/* OS/2: x - Position of bottom left corner  */</span>
                 <span style="color: #ff0000; font-style: italic;">/* OS/2: y - relative to visible netscape window */</span>
  <span style="color: #0000ff;">int32</span> x<span style="color: #008080;">;</span>       <span style="color: #ff0000; font-style: italic;">/* Position of top left corner relative */</span>
  <span style="color: #0000ff;">int32</span> y<span style="color: #008080;">;</span>       <span style="color: #ff0000; font-style: italic;">/* to a netscape page.					*/</span>
  <span style="color: #0000ff;">uint32</span> width<span style="color: #008080;">;</span>  <span style="color: #ff0000; font-style: italic;">/* Maximum window size */</span>
  <span style="color: #0000ff;">uint32</span> height<span style="color: #008080;">;</span>
  NPRect clipRect<span style="color: #008080;">;</span> <span style="color: #ff0000; font-style: italic;">/* Clipping rectangle in port coordinates */</span>
                   <span style="color: #ff0000; font-style: italic;">/* Used by MAC only.			  */</span>
  <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span> ws_info<span style="color: #008080;">;</span> <span style="color: #ff0000; font-style: italic;">/* Platform-dependent additonal data, linux specific */</span>
  NPWindowType type<span style="color: #008080;">;</span> <span style="color: #ff0000; font-style: italic;">/* Is this a window or a drawable? */</span>
<span style="color: #008000;">&#125;</span> NPWindow<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>A pointer to this structure is passed in with each call.  On windows, the &#8220;<em>void* window</em>&#8221; will dereference to an <em>HWND</em>. On other platforms, it will likewise be dereferenced as an appropriate type.</p>
<p>Notice that again <em>NPP npp</em> is the first parameter.  This will be the case on all NPP functions except <a title="NPP_New API doc" href="https://developer.mozilla.org/En/NPP_New" target="_blank">NPP_New</a>, where the mimetype is also passed in.  Since we created a PluginInstance object and assigned it to npp->pdata in <a title="NPP_New API doc" href="https://developer.mozilla.org/En/NPP_New" target="_blank">NPP_New</a>, we need to create a small stub function to forward our NPP_New to a method on that object, like so:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Called by browser whenever the window is changed, including to set up or destroy</span>
NPErrorNPP_SetWindow <span style="color: #008000;">&#40;</span>NPP npp, NPWindow<span style="color: #000040;">*</span> pNPWindow<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>npp <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> NPERR_INVALID_INSTANCE_ERROR<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>npp<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>pdata <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> NPERR_GENERIC_ERROR<span style="color: #008080;">;</span>
&nbsp;
    PluginInstance <span style="color: #000040;">*</span>inst <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>PluginInstance <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>npp<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>pdata<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> inst<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>NpapiSetWindow<span style="color: #008000;">&#40;</span>pNPWindow<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>On windows, when SetWindow is called we need to save the HWND and subclass the window so that we can get our own window event proc.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPError PluginInstance<span style="color: #008080;">::</span><span style="color: #007788;">NpapiSetWindow</span> <span style="color: #008000;">&#40;</span>NPWindow<span style="color: #000040;">*</span> pNPWindow<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    NPError rv <span style="color: #000080;">=</span> NPERR_NO_ERROR<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>pNPWindow <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> NPERR_GENERIC_ERROR<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// window just created; in initWindow, set initialized to true</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>initialized<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>initWindow<span style="color: #008000;">&#40;</span>pNPWindow<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">return</span> NPERR_MODULE_LOAD_FAILED_ERROR<span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #666666;">// Window was already created; just pass on the updates</span>
    this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>updateWindow<span style="color: #008000;">&#40;</span>pNPWindow<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> rv<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>With these functions, we get notified in one function when the window is first set, and another is called each time an update is made.</p>
<h3>NPP_Destroy (NPP npp, NPSavedData** save)</h3>
<p>When the Browser is ready to shut down a given plugin instance (the user leaves the page or the object tag is removed from the DOM), the browser calls <a title="NPP_Destroy sdk docs" href="https://developer.mozilla.org/En/NPP_Destroy">NPP_Destroy</a>.  This call is responsible to free any memory being used by that plugin instance.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Called by browser to destroy an instance of the plugin</span>
NPError NPP_Destroy <span style="color: #008000;">&#40;</span>NPP npp, NPSavedData<span style="color: #000040;">**</span> save<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>npp <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> NPERR_INVALID_INSTANCE_ERROR<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>npp<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>pdata <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> NPERR_GENERIC_ERROR<span style="color: #008080;">;</span>
&nbsp;
    PluginInstance <span style="color: #000040;">*</span>inst <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>PluginInstance <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>npp<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>pdata<span style="color: #008080;">;</span>
    NPError rv <span style="color: #000080;">=</span> inst<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>NpapiDestroy<span style="color: #008000;">&#40;</span>save<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">delete</span> getPluginObject<span style="color: #008000;">&#40;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    npp<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>pdata <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> rv<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<h3>Next Time</h3>
<p>That&#8217;s all the time I have today.  Next time <a title="Building a firefox plugin - part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-%E2%80%93-part-three/">I will discuss NPObjects and how they are used</a> to provide an interface by which Javascript can interact with your plugin.</p>
<p><a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/">Building a firefox plugin &#8211; part one</a></p>
<p><a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">Building a firefox plugin &#8211; part two</a></p>
<p><a title="Building a firefox plugin - part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/">Building a firefox plugin &#8211; part three</a></p>
<p><a title="Building a firefox plugin - part four" href="http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/">Building a firefox plugin &#8211; part four</a></p>
<h2>Getting more help</h2>
<p><strong>Update May 14, 2011:</strong> Many people have been asking questions in the comments; while I don&#8217;t mind that, it would probably be more useful if you ask your question on <a href="http://forum.firebreath.org">the FireBreath forums</a>. There is a forum there for those just using NPAPI as well!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>Building a firefox plugin – part one</title>
		<link>http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/</link>
		<comments>http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 20:05:53 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=42</guid>
		<description><![CDATA[Note: For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the FireBreath project. Getting help: For a better place to ask NPAPI-related questions, check out the FireBreath Forums. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well. Introduction [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: </strong>For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the <a href="http://www.firebreath.org">FireBreath project</a>.</p>
<p><strong>Getting help: </strong>For a better place to ask NPAPI-related questions, check out the <a href="http://forum.firebreath.org">FireBreath Forums</a>. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well.</p>
<h2>Introduction</h2>
<p>I have now been researching and working on a cross-platform browser plugin for several months.  By far my greatest frustration throughout this process has been the significant lack of documentation on the subject.  So, with the creation of this site, I wish to create a small series that will hopefully provide assistance to other poor developers who are trying to break into this strangely secretive field =]</p>
<p>I&#8217;m not going to be able to cover everything in one post (for time reasons if nothing else).  How fast I get the rest of the posts done may depend in large part on whether or not anyone seems to be reading them and what requests are made in the comments =]</p>
<h3>Plugin architecture</h3>
<p>In these articles I plan to focus on the basic requirements for creating an NPAPI (Netscape Plugin) style plugin, which is used by most (if not all) plugin-supporting open browsers, including: Apple Internet Plugins on Mac (Firefox, Safari, probably others); Firefox (and all other gecko-based browsers), Opera, Safari, and Chrome on windows, and at least firefox on linux.  I haven&#8217;t yet implemented a plugin on linux, but most of the same principles should apply.</p>
<p><span id="more-42"></span>Because of the minor differences between platforms, I will first cover the architecture as it is used in Windows, and then in a later post I will cover the differences between windows and other platforms, such as Mac and Linux.</p>
<h3>Plugin API vs Scripting API</h3>
<p>When I first began developing browser plugins, I failed to understand the difference between the scripting API and the plugin API.  They are closely related, of course, but they serve different purposes.</p>
<p>The <em>Scripting API</em> is used to provide methods callable from javascript, while the <em>Browser API</em> provides the interface for hosting the plugin itself in the browser.</p>
<h4>NPAPI</h4>
<p>You can find the Mozilla documentation for plugins here:</p>
<p><a title="Gecko Plugin API Reference" href="https://developer.mozilla.org/en/Gecko_Plugin_API_Reference" target="_blank">https://developer.mozilla.org/en/Gecko_Plugin_API_Reference</a></p>
<p>For history of the NPAPI (Netscape Plugin API), see the <a title="NPAPI on Wikipedia" href="http://en.wikipedia.org/wiki/NPAPI" target="_blank">Wikipedia page: http://en.wikipedia.org/wiki/NPAPI</a></p>
<h2>What makes up an NPAPI browser plugin?</h2>
<p>A NPAPI browser plugin is, at it&#8217;s core, simply a DLL with a few specific entry points.  Each of these entry points is only called once by the browser for all instances of your plugin on a given page.  They are listed here in the order they should be called:</p>
<ul>
<li><a title="Gecko API reference" href="https://developer.mozilla.org/Talk:En/Gecko_Plugin_API_Reference/Plug-in_Side_Plug-in_API">NP_GetEntryPoints</a> &#8211; Called immediately after the plugin is loaded and is used by the browser (no longer just netscape) to get pointers to all of the API functions that the browser might need to call.</li>
<li><a title="Gecko NPAPI reference: NP_Initialize" href="https://developer.mozilla.org/En/NP_Initialize">NP_Initialize</a> &#8211; Provides global initialization of your plugin.</li>
<li><a title="Gecko NPAPI reference: NP_Shutdown" href="https://developer.mozilla.org/En/NP_Shutdown" target="_blank">NP_Shutdown</a> &#8211; Provides global deinitialization of your plug-in.</li>
</ul>
<p>It is important to note that since these entrypoints are specific to NPAPI, there is no reason you can&#8217;t have a NPAPI plugin inside a DLL that also provides other services (like, for example, an ActiveX plugin).</p>
<p>Since these three entrypoints provide the core of the NPAPI architecture, it is worth our time to look at them a little more closely.</p>
<h3>NP_GetEntryPoints</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPError WINAPI NP_GetEntryPoints<span style="color: #008000;">&#40;</span>NPPluginFuncs<span style="color: #000040;">*</span> pFuncs<span style="color: #008000;">&#41;</span></pre>
</div>
</div>
<p>This is undoubtedly the most important of the three to understand.  Because of this, it shocks me that the only actual useful documentation I have found for this method so far is found in <a title="Web Programming Unleashed" href="http://www.webbasedprogramming.com/Web-Programming-Unleashed/ch32.htm" target="_blank">an old, but still mostly accurate web-book</a> written who-knows-when by Zan Oliphant.</p>
<p>While not as straightforward as the other two entrypoint functions, NP_GetEntryPoints is nonetheless relatively straightforward.  As you can see from the above function prototype, NP_GetEntryPoints takes a pointer to the NPPluginFuncs structure:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPPluginFuncs <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">uint16</span> size<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">uint16</span> version<span style="color: #008080;">;</span>
    NPP_NewUPP newp<span style="color: #008080;">;</span>
    NPP_DestroyUPP destroy<span style="color: #008080;">;</span>
    NPP_SetWindowUPP setwindow<span style="color: #008080;">;</span>
    NPP_NewStreamUPP newstream<span style="color: #008080;">;</span>
    NPP_DestroyStreamUPP destroystream<span style="color: #008080;">;</span>
    NPP_StreamAsFileUPP asfile<span style="color: #008080;">;</span>
    NPP_WriteReadyUPP writeready<span style="color: #008080;">;</span>
    NPP_WriteUPP write<span style="color: #008080;">;</span>
    NPP_PrintUPP print<span style="color: #008080;">;</span>
    NPP_HandleEventUPP event<span style="color: #008080;">;</span>
    NPP_URLNotifyUPP urlnotify<span style="color: #008080;">;</span>
    JRIGlobalRef javaClass<span style="color: #008080;">;</span>
    NPP_GetValueUPP getvalue<span style="color: #008080;">;</span>
    NPP_SetValueUPP setvalue<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> NPPluginFuncs<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>UPP in each of these type names stands for &#8220;Universal Proc Pointer&#8221;, which is essentially just a function pointer that the Gecko SDK uses in conjunction with a CallUniversalProc macro for all of its function pointer needs.  For more information, grep the Gecko SDK.</p>
<p>These function pointers basically tell the browser how to interact with your plugin.  Notice the naming convention here: NPP_* for all plugin functions.  There are also NPN_* functions that we will see later, and these are functions that the plugin can call on the browser.  They will be given to us in the NP_Initialize call.</p>
<p>So, the primary purpose of the NP_GetEntryPoints function is to give the browser pointers to all of the functions that it needs to call when creating or interacting with your plugin.</p>
<p>Here is a quick overview of the NPP plugin functions that your plugin must provide (and give addresses to when NP_GetEntryPoints is called).  This table is copied from <a title="A Quick Look at the Plug-In API Methods (Zan Oliphant)" href="http://docs.rinet.ru/Plugi/ch8.htm#AQuickLookatthePlugInAPIMethods">Zan Oliphant&#8217;s book</a> and updated to reflect the current practices and Gecko SDK 1.8:</p>
<table style="height: 304px;" border="1" width="539" bordercolor="#000000">
<tbody>
<tr>
<td><em>API Name</em></td>
<td width="322"><em>Description</em></td>
</tr>
<tr>
<td width="186"><a title="NPP_New API doc" href="https://developer.mozilla.org/En/NPP_New" target="_blank"><tt><span style="font-family: Courier;">NPP_New</span></tt></a></td>
<td width="322">Creates a new instance of a plug-in.</td>
</tr>
<tr>
<td width="186"><a title="NPP_Destroy API doc" href="https://developer.mozilla.org/En/NPP_Destroy" target="_blank"><tt><span style="font-family: Courier;">NPP_Destroy</span></tt></a></td>
<td width="322">Deletes an instance of a plug-in.</td>
</tr>
<tr>
<td width="186"><a title="NPP_SetWindow API doc" href="https://developer.mozilla.org/En/NPP_SetWindow" target="_blank"><tt><span style="font-family: Courier;">NPP_SetWindow</span></tt></a></td>
<td width="322">Tells the plug-in when a window is created, moved, sized, or destroyed.</td>
</tr>
<tr>
<td width="186"><a title="NPP_NewStream API doc" href="https://developer.mozilla.org/En/NPP_NewStream" target="_blank"><tt><span style="font-family: Courier;">NPP_NewStream</span></tt></a></td>
<td width="322">Notifies a plug-in instance of a new data stream.</td>
</tr>
<tr>
<td width="186"><a title="NPP_DestroyStream API Doc" href="https://developer.mozilla.org/En/NPP_DestroyStream" target="_blank"><tt><span style="font-family: Courier;">NPP_DestroyStream</span></tt></a></td>
<td width="322">Tells the plug-in that a stream is about to be closed or destroyed.</td>
</tr>
<tr>
<td width="186"><a title="NPP_StreamAsFile API Doc" href="https://developer.mozilla.org/En/NPP_StreamAsFile" target="_blank"><tt><span style="font-family: Courier;">NPP_StreamAsFile</span></tt></a></td>
<td width="322">Provides a local file name for the data from a stream.</td>
</tr>
<tr>
<td width="186"><a title="NPP_WriteReady API doc" href="https://developer.mozilla.org/En/NPP_WriteReady" target="_blank"><tt><span style="font-family: Courier;">NPP_WriteReady</span></tt></a></td>
<td width="322">Determines whether a plug-in is ready for data (and the maximum number of bytes it is prepared to accept).</td>
</tr>
<tr>
<td width="186"><a title="NPP_Write API doc" href="https://developer.mozilla.org/En/NPP_Write" target="_blank"><tt><span style="font-family: Courier;">NPP_Write</span></tt></a></td>
<td width="322">Called to write/deliver data to a plug-in.  The docs note that this might be better named &#8220;NPP_DataArrived&#8221;.</td>
</tr>
<tr>
<td width="186"><a title="NPP_Print API doc" href="https://developer.mozilla.org/En/NPP_Print" target="_blank"><tt><span style="font-family: Courier;">NPP_Print</span></tt></a></td>
<td width="322">Requests a platform-specific print operation for an embedded or full-screen plug-in.</td>
</tr>
<tr>
<td width="186"><a title="NPP_HandleEvent" href="https://developer.mozilla.org/En/NPP_HandleEvent" target="_blank"><tt><span style="font-family: Courier;">NPP_HandleEvent</span></tt></a></td>
<td width="322">Event handler, currently only used by Windowed plugins on Mac OS; windowless plugins on all platforms use this.</td>
</tr>
<tr>
<td width="186"><a title="NPP_URLNotify API doc" href="https://developer.mozilla.org/En/NPP_URLNotify" target="_blank"><tt><span style="font-family: Courier;">NPP_URLNotify</span></tt></a></td>
<td width="322">Notifies the completion of a URL request.</td>
</tr>
<tr>
<td width="186"><tt><span style="font-family: Courier;">NPP_GetJavaClass</span></tt></td>
<td width="322">Deprecated / No longer used. Set to NULL</td>
</tr>
<tr>
<td width="186"><a title="NPP_GetValue API doc" href="https://developer.mozilla.org/En/NPP_GetValue" target="_blank"><tt><span style="font-family: Courier;">NPP_GetValue</span></tt></a></td>
<td width="322">Called to query the plugin for information (also used to get an instance of a NPObject/Scriptable Plugin)</td>
</tr>
<tr>
<td width="186"><a title="NPP_SetValue API doc" href="https://developer.mozilla.org/En/NPP_SetValue" target="_blank"><tt><span style="font-family: Courier;">NPP_SetValue</span></tt></a></td>
<td width="322">This call is used to inform plugins of variable information controlled by the browser.</td>
</tr>
</tbody>
</table>
<p>We will talk more about the specifics of how each of these functions works later.</p>
<h3>NP_Initialize</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPError WINAPI NP_Initialize<span style="color: #008000;">&#40;</span>NPNetscapeFuncs <span style="color: #000040;">*</span>aNPNFuncs<span style="color: #008000;">&#41;</span> <span style="color: #666666;">// Windows</span>
<span style="color: #666666;">// -or-</span>
NPError NP_Initialize<span style="color: #008000;">&#40;</span>NPNetscapeFuncs <span style="color: #000040;">*</span>aNPNFuncs, NPPluginFuncs <span style="color: #000040;">*</span>aNPPFuncs<span style="color: #008000;">&#41;</span> <span style="color: #666666;">// Linux</span></pre>
</div>
</div>
<p>As noted in the <a title="NP_Initialize API doc" href="https://developer.mozilla.org/En/NP_Initialize" target="_blank">documentation</a>, NP_Initialize provides global initialization for a plug-in.  The API reference is a little confusing in that it claims that NP_Initialize is actually the first function called by the browser.  The reason for this is that on linux, there aparently is no NP_GetEntryPoints call; instead, the NPPluginFuncs struct is passed into the NP_Initialize function to be filled out.</p>
<p>Since this isn&#8217;t confusing enough, on Mac they have replaced both of these functions with a single &#8220;main&#8221; function that not only gets passed both function pointer structures (one with the browser functions and one to be filled out with plugin functions) but also is given a shutdown function pointer to be filled out with the address to the NP_Shutdown function.</p>
<p>Because of these discrepancies, I recommend that you write a separate function for filling out the NPPluginFuncs structure so that it can be called from any of the various init functions.</p>
<p>The NPNetscapeFuncs structure that is passed in is the complement to the NPPluginFuncs structure that we have discussed previously.  As might be guessed from the name, the NPNetscapeFuncs structure contains pointers to browser functions that can be called by the plugin.  There are a lot more of these, and we will discuss more about how to use them next time.</p>
<p>For now, take a look at the structure to get a general idea of what is there.  I&#8217;ve added comments on some of the more common function calls.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPNetscapeFuncs <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">uint16</span> size<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">uint16</span> version<span style="color: #008080;">;</span> <span style="color: #666666;">// Newer versions may have additional fields added to the end</span>
    NPN_GetURLUPP geturl<span style="color: #008080;">;</span> <span style="color: #666666;">// Make a GET request for a URL either to the window or another stream</span>
    NPN_PostURLUPP posturl<span style="color: #008080;">;</span> <span style="color: #666666;">// Make a POST request for a URL either to the window or another stream</span>
    NPN_RequestReadUPP requestread<span style="color: #008080;">;</span>
    NPN_NewStreamUPP newstream<span style="color: #008080;">;</span>
    NPN_WriteUPP write<span style="color: #008080;">;</span>
    NPN_DestroyStreamUPP destroystream<span style="color: #008080;">;</span>
    NPN_StatusUPP status<span style="color: #008080;">;</span>
    NPN_UserAgentUPP uagent<span style="color: #008080;">;</span>
    NPN_MemAllocUPP memalloc<span style="color: #008080;">;</span> <span style="color: #666666;">// Allocates memory from the browser's memory space</span>
    NPN_MemFreeUPP memfree<span style="color: #008080;">;</span> <span style="color: #666666;">// Frees memory from the browser's memory space</span>
    NPN_MemFlushUPP memflush<span style="color: #008080;">;</span>
    NPN_ReloadPluginsUPP reloadplugins<span style="color: #008080;">;</span>
    NPN_GetJavaEnvUPP getJavaEnv<span style="color: #008080;">;</span>
    NPN_GetJavaPeerUPP getJavaPeer<span style="color: #008080;">;</span>
    NPN_GetURLNotifyUPP geturlnotify<span style="color: #008080;">;</span> <span style="color: #666666;">// Async call to get a URL</span>
    NPN_PostURLNotifyUPP posturlnotify<span style="color: #008080;">;</span> <span style="color: #666666;">// Async call to post a URL</span>
    NPN_GetValueUPP getvalue<span style="color: #008080;">;</span> <span style="color: #666666;">// Get information from the browser</span>
    NPN_SetValueUPP setvalue<span style="color: #008080;">;</span> <span style="color: #666666;">// Set information about the plugin that the browser controls</span>
    NPN_InvalidateRectUPP invalidaterect<span style="color: #008080;">;</span>
    NPN_InvalidateRegionUPP invalidateregion<span style="color: #008080;">;</span>
    NPN_ForceRedrawUPP forceredraw<span style="color: #008080;">;</span>
    NPN_GetStringIdentifierUPP getstringidentifier<span style="color: #008080;">;</span> <span style="color: #666666;">// Get a NPIdentifier for a given string</span>
    NPN_GetStringIdentifiersUPP getstringidentifiers<span style="color: #008080;">;</span>
    NPN_GetIntIdentifierUPP getintidentifier<span style="color: #008080;">;</span>
    NPN_IdentifierIsStringUPP identifierisstring<span style="color: #008080;">;</span>
    NPN_UTF8FromIdentifierUPP utf8fromidentifier<span style="color: #008080;">;</span> <span style="color: #666666;">// Get a string from a NPIdentifier</span>
    NPN_IntFromIdentifierUPP intfromidentifier<span style="color: #008080;">;</span>
    NPN_CreateObjectUPP createobject<span style="color: #008080;">;</span> <span style="color: #666666;">// Create an instance of a NPObject</span>
    NPN_RetainObjectUPP retainobject<span style="color: #008080;">;</span> <span style="color: #666666;">// Increment the reference count of a NPObject</span>
    NPN_ReleaseObjectUPP releaseobject<span style="color: #008080;">;</span> <span style="color: #666666;">// Decrement the reference count of a NPObject</span>
    NPN_InvokeUPP invoke<span style="color: #008080;">;</span> <span style="color: #666666;">// Invoke a method on a NPObject</span>
    NPN_InvokeDefaultUPP invokeDefault<span style="color: #008080;">;</span> <span style="color: #666666;">// Invoke the default method on a NPObject</span>
    NPN_EvaluateUPP evaluate<span style="color: #008080;">;</span> <span style="color: #666666;">// Evaluate javascript in the scope of a NPObject</span>
    NPN_GetPropertyUPP getproperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Get a property on a NPObject</span>
    NPN_SetPropertyUPP setproperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Set a property on a NPObject</span>
    NPN_RemovePropertyUPP removeproperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Remove a property from a NPObject</span>
    NPN_HasPropertyUPP hasproperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Returns true if the given NPObject has the given property</span>
    NPN_HasMethodUPP hasmethod<span style="color: #008080;">;</span> <span style="color: #666666;">// Returns true if the given NPObject has the given Method</span>
    NPN_ReleaseVariantValueUPP releasevariantvalue<span style="color: #008080;">;</span> <span style="color: #666666;">// Release a MNVariant (free memory)</span>
    NPN_SetExceptionUPP setexception<span style="color: #008080;">;</span>
    NPN_PushPopupsEnabledStateUPP pushpopupsenabledstate<span style="color: #008080;">;</span>
    NPN_PopPopupsEnabledStateUPP poppopupsenabledstate<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> NPNetscapeFuncs<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>In addition to saving the function pointers given so that browser calls can be made, any memory that is to be shared by all instances of your browser plugin should be initialized here.</p>
<h3>NP_Shutdown</h3>
<p>This is the simplest of the three entrypoints.  Free any shared memory and release any shared resources.  This is called when the browser has already destroyed all instances of your plugin (by calling <a title="NPP_Destroy API doc" href="https://developer.mozilla.org/En/NPP_Destroy" target="_blank">NPP_Destroy</a>) and does not expect to create any more in the near future.</p>
<h2>Next Time</h2>
<p>Next time we will go into greater detail on implementing the NPP functions and also cover some of the most commonly used NPN functions.</p>
<p><a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/">Building a firefox plugin &#8211; part one</a></p>
<p><a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">Building a firefox plugin &#8211; part two</a></p>
<p><a title="Building a firefox plugin - part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/">Building a firefox plugin &#8211; part three</a></p>
<p><a title="Building a firefox plugin - part four" href="http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/">Building a firefox plugin &#8211; part four</a></p>
<h2>Getting more help</h2>
<p><strong>Update May 14, 2011:</strong> Many people have been asking questions in the comments; while I don&#8217;t mind that, it would probably be more useful if you ask your question on <a href="http://forum.firebreath.org">the FireBreath forums</a>. There is a forum there for those just using NPAPI as well!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/feed/</wfw:commentRss>
		<slash:comments>99</slash:comments>
		</item>
	</channel>
</rss>

