NPAPI插件開發詳細記錄:用VS2010開發NPAPI插件步驟

http://blog.csdn.net/z6482/article/details/7660748

前面一段時間關注了用firebreath開發插件,但是感覺用起來不是那麼得心應手,還是回到NPAPI開發插件上來。

本文根據NPAPI開發詳解,Windows版進行開發,其中以VS2008爲例進行開發,在VS2010中基本上是相同的。
必須的plugin sdk,將其解壓到某個目錄下,我這裏是:D:\Users\zcf\Documents\My Program\2012。下面是創建插件的步驟:

1、創建項目


名稱一定要以np開頭,爲了將來適應不同操作系統,最好全小寫,不要太長,儘量控制在8字符內。本例定義爲npmedia
位置指定到~plugin\sdk\samples
點擊確定、下一步。選擇dll、空項目:


點擊完成,即建立好了一個空項目。如下圖:

2、添加必要文件

首先,添加NPAPI SDK中的Common文件,共三個:


然後添加def文件:


編輯npdemo.def爲:

  1. LIBRARY "npmedia"  
  2.   
  3. EXPORTS  
  4. NP_GetEntryPoints @1  
  5. NP_Initialize @2  
  6. NP_Shutdown @3  
LIBRARY "npmedia"

EXPORTS
NP_GetEntryPoints @1
NP_Initialize @2
NP_Shutdown @3

接着添加資源文件:


自動生成了resource.h和npdemo.rc。接着修改rc文件:



在圖中的BLOCK內添加。注意!BLOCK 一定要爲"040904e4"
VALUE "MIMEType", "application/media-plugin"

注意:有很多朋友反映按照本文的方法做出的插件在chrome中無法識別,問題就在於此處,將下一個字段改爲如下形式就可以了:

BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END

這裏補充一點:BLOCK  "040904e4"與後面VALUE "Translation", 0x409, 1252的含義是對應的,1252的十六進制表示就是4e4.Translation字段的第一個值表示語言409表示英語,而默認的804表示中文(簡體)。Translation字段的第二個值表示所採用的字符集,1200(0X04B0)表示unicode,1252(0X04E4)表示多字節字符集,請參考:http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa381057%28v=vs.85%29.aspx。對於用中文環境開發來講既可以用409(英語)也可以用804(中文)

BLOCK 的值對於firefox必須是 "040904e4",有朋友提到在chrome中這個BLOCK 的值可以是 "080404e4"

如果要支持chrome則字符集應設置爲1252(0X04E4)如要及支持firefox又支持chrome,保險的做法是

BLOCK  "040904e4"對應"Translation", 0x409, 1252


3、添加Plugin實現類




類名可以隨便命名,但是必須繼承自nsPluginInstanceBase。
編輯Plugin.h:

  1. #pragma once  
  2. #include "pluginbase.h"  
  3.   
  4. class Plugin :  
  5. public nsPluginInstanceBase  
  6. {  
  7. private:  
  8. NPP m_pNPInstance;  
  9. NPBool m_bInitialized;  
  10. public:  
  11. Plugin(NPP pNPInstance);  
  12. ~Plugin();  
  13.   
  14. NPBool init(NPWindow* pNPWindow) { m_bInitialized = TRUE; return TRUE;}  
  15. void shut() { m_bInitialized = FALSE; }  
  16. NPBool isInitialized() { return m_bInitialized; }  
  17. };  
#pragma once
#include "pluginbase.h"

class Plugin :
public nsPluginInstanceBase
{
private:
NPP m_pNPInstance;
NPBool m_bInitialized;
public:
Plugin(NPP pNPInstance);
~Plugin();

NPBool init(NPWindow* pNPWindow) { m_bInitialized = TRUE; return TRUE;}
void shut() { m_bInitialized = FALSE; }
NPBool isInitialized() { return m_bInitialized; }
};


編輯Plugin.cpp:


  1. #include "Plugin.h"  
  2.   
  3. ////// functions /////////  
  4. NPError NS_PluginInitialize()  
  5. {  
  6. return NPERR_NO_ERROR;  
  7. }  
  8.   
  9. void NS_PluginShutdown()  
  10. {  
  11. }  
  12.   
  13. nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)  
  14. {  
  15. if(!aCreateDataStruct)  
  16. return NULL;  
  17.   
  18. Plugin * plugin = new Plugin(aCreateDataStruct->instance);  
  19. return plugin;  
  20. }  
  21.   
  22. void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin)  
  23. {  
  24. if(aPlugin)  
  25. delete (Plugin *)aPlugin;  
  26. }  
  27.   
  28. ////// Plugin /////////  
  29. Plugin::Plugin(NPP pNPInstance):nsPluginInstanceBase(),  
  30. m_pNPInstance(pNPInstance),  
  31. m_bInitialized(FALSE)  
  32. {  
  33. }  
  34.   
  35.   
  36. Plugin::~Plugin(void)  
  37. {  
  38. }  
#include "Plugin.h"

////// functions /////////
NPError NS_PluginInitialize()
{
return NPERR_NO_ERROR;
}

void NS_PluginShutdown()
{
}

nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)
{
if(!aCreateDataStruct)
return NULL;

Plugin * plugin = new Plugin(aCreateDataStruct->instance);
return plugin;
}

void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin)
{
if(aPlugin)
delete (Plugin *)aPlugin;
}

////// Plugin /////////
Plugin::Plugin(NPP pNPInstance):nsPluginInstanceBase(),
m_pNPInstance(pNPInstance),
m_bInitialized(FALSE)
{
}


Plugin::~Plugin(void)
{
}


4、修改項目屬性



字符集選擇爲多字節字符(不是必須的),下面添加包含文件:



5、編譯調試

完成了上述設置就可以進行編譯調試了。
這是整個項目的結構:


生成該項目之後,可以在項目的Debug目錄下找到dll文件,這裏是npmedia.dll。可以寫註冊表註冊這個dll,也可以將這個dll複製到用來測試插件的Firefox的profile目錄下的plugins(沒有則自行創建)文件夾中。
寫註冊表的方式:運行regedit,在HKEY_LOCAL_MACHINE\SOFTWARE\MozillaPlugins下建立一個子項,可隨意命名:這裏以@zcf.com/media爲例,新建字符串項Path,其值爲生成的dll的路徑:


注意,這種方式在XP系統下測試通過,在WIN7系統下沒有成功(注意:win7 64位應運行 %windir%\SysWOW64\Regedit.exe,打開的就是64註冊表,可以在HKEY_LOCAL_MACHINE\SOFTWARE\MozillaPlugins下看到很多64位版本的插件,多謝網友 Jearol 告知)。還有一種方式就是設置項目屬性,將輸出目錄指定爲用來調試的Firefox相應profile目錄下的plugins目錄。這樣就不用每次生成之後來回複製dll。如下圖:


然後在Firefox地址欄中輸入about:plugins就可以看到我們的插件了。
測試頁面可以如下:
測試文件mediatest.html:

  1. <!doctype html>  
  2. <html>  
  3. <title>TEST WEB PAGE for media plugin</title>  
  4. <body>  
  5. <object type="application/media-plugin" width=200 height=150 ></object>  
  6. <br />  
  7. </body>  
  8. </html>  
<!doctype html>
<html>
<title>TEST WEB PAGE for media plugin</title>
<body>
<object type="application/media-plugin" width=200 height=150 ></object>
<br />
</body>
</html>


關於調試插件:首先用Firefox打開測試頁面,然後在VS2010中需要的地方設置斷點,接着選擇調試/附加到進程在彈出的對話框中選擇plugin-container.exe,可能不止一個,注意根據其路徑選擇正確的那個。最後刷新測試頁面就可以在你設置的斷點的地方斷下,進行調試。下一篇文章會有一個簡單的實例展示這個調試過程。


發佈了7 篇原創文章 · 獲贊 6 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章