NPAPI和PPAPI开发
https://blog.csdn.net/lee353086/article/details/49302917
環境:
?[1]Visual Studio 2010 SP1
? ? Visaul Stuio ?2013 Update4
?[2]Python2.7
?[3]Firefox 41.0.1
?[4]IE 11
?[5]Google chrome 45.0.2454.101?
?[6]Opera 32.0
?[7]360瀏覽器 7.1.1.808
?[8]nacl sdk pepper39?
?[9]windows7 SP1 64bits關鍵詞
? ?Firebreath, NPAPI, PPAPI, Web worker, Messaging System, Native Client Module, Application Structure
? ?Chrome Web Store, portable executable file, architecture-specific executable file?
? ?前言 ?
? ? 如果要實現Windows平臺,跨不同瀏覽器插件,就需要分別實現
? ? ActiveX ?適用瀏覽器IE11,因為IE11對FireBreath兼容性不是很好。
? ? FreBreath(NPAPI) ?適用瀏覽器,360瀏覽器,Chrome 42版本以下,Opera、Firefox。
? ? NaCl(可分為PPAPI、NaCl、PNaCl三個等級) 適用瀏覽器Chrome 42版本或以上。
? ? ActiveX的baidu上很多,但是NPAPI和PPAPI的很不完善,所以這里僅僅介紹NPAPI和PPAPI的開發。第一部份:NPAPI
第一個插件(NPAPI):
? ?firebreath是個跨瀏覽器插件開發工具,所以先嘗試FireBreath。Step1:
? 參考資料[3]下載firebreath最新穩定版本,并解壓到“D:\SDK\firebreath-FireBreath-105dcc6\”目錄下
? 從官網上下載firebreath-boost-1.50.0.zip
? 位置參考下面擺放:
? <FB_ROOT>/src/3rdParty/boost/boost/
? <FB_ROOT>/src/3rdParty/boost/libs/Step2:先建一個Hello工程。
?打開控制臺,切換到“D:\SDK\firebreath-FireBreath-105dcc6”文件夾,
? ?輸入命令“python fbgen.py”根據提示輸入你第一個工程plugin name,plugin description,company name等信息。
? ?命令執行完畢后,再調用“prep2010.cmd”命令。
? ?python就在當前build子目錄下建好了VS2010 solution,FireBreath.sln文件。
? 打開sln后應該就能正確編譯。如果有問題參考資料[1]。Step3:測試插件是否正確加載。
[S3-1]IE下運行插件。
? 命令行方式轉到“D:\SDK\firebreath-FireBreath-105dcc6\build\bin\hello\Debug”路徑下,使用“regsvr32 nphello.dll”注冊控件。
? "D:\SDK\firebreath-FireBreath-105dcc6\build\projects\hello\gen"路徑下打開“FBControl.htm”文件,就可以在IE中正常運行hello控件。
? 如果有問題,參考資料[2]。
[S3-2]Firefox下運行插件
? 我是把dll復制到“C:\Users\kagula\AppData\Roaming\Mozilla\Firefox\Profiles\ie1ypj6h.default\plugins”路徑就Ok了,如果沒有“plugins”目錄就新建一個。
? 不同的計算機Win7下,參考下面的格式就Ok了。
? “C:\Users\XXX\AppData\Roaming\Mozilla\Firefox\Profiles\XXX.default\plugins”
[S3-3]Chrome下運行
? Chrome 45 不支持NPAPI。
[S3-4]Opera下運行
? 使用“regsvr32 nphello.dll”注冊控件后,可以直接使用,
但是會提示“此網站使用的插件很快將不被支持”
[S3-5]360瀏覽器下運行
? 使用“regsvr32 nphello.dll”注冊控件后,可以直接使用,Step4:測試插件功能是否正常
?[1]hello.cpp的FB::JSAPIPtr hello::createJSAPI()函數,創建了helloAPI實例返回。
?查看helloAPI實現,
? echo方法用來示例參數傳遞,testEvent方法示例事件回調,testString和version示例如何存取對象的屬性。
?[2]FBControl.htm文件,點擊“Fire a test event”會間接調用helloAPI實例的testEvent方法,這個方法又會激活JS的test事件。
? 在IE中沒有反應,但是在Opera和360瀏覽器中測試正常。
?[3]FBControl.htm文件,點擊“Activate click counter”,就多一次對插件echo事件的綁定。
? ? 然后,再點擊“Click me!”,JS會調用插件的echo方法,而插件的echo方法會調用js對echo事件的綁定function。
? ? 在IE中依舊沒有反應。
?[4]測試插件屬性的存取,
? [S4-1]為FBControl.htm文件,添加一個js函數。
? ? function testPluginPropertyAccess(){alert(plugin().testString);plugin().testString = "插件屬性的默認值已經被JS修改";alert(plugin().testString);}
? ?為FBControl.htm文件,添加一個鏈接,可以讓用戶點擊。
? ?<a href="#" οnclick="javascript:testPluginPropertyAccess()">測試對屬性值的修改</a> <br />
? ?[S4-2]修改helloAPI.h文件,在helloAPI的構造函數中添加下面的代碼。
? ?m_testString = "Default value in c++";
? ?這樣我們才能知道這個屬性的值是來自C++代碼的。
? ?[S4-3]然后再參考上文,測試即可。
?[Step5]驗證是否能自繪區域
? ?一開始在"hello"項目上onWindowAttached死活不會來,后來又重建了一個firegbreath項目就好了。
? ?猜測是用fbgen.py新建項目時,輸入的參數不對。
? ?下面是我的測試函數,我往plugin api里注冊了“draw”函數,用來測試能否繪制html表面。
? ?void helloAPI::draw()
{if (_wnd) {HDC hDC = GetDC(_wnd->getHWND());RECT rect;rect.left=0,rect.top=0,rect.right=256,rect.bottom=256;HBRUSH hbr;hbr = CreateSolidBrush(RGB(255,0,0));FillRect(hDC,&rect,hbr);ReleaseDC(_wnd->getHWND(),hDC);}
}
? ? 具體參考“...\firebreath-FireBreath-105dcc6\examples\BasicMediaPlayer”目錄下的源代碼。
備注
?[1]Firebreath缺省沒有連接下面兩個事件:EVENTTYPE_CASE(FB::RefreshEvent, draw, FB::PluginWindow);EVENTTYPE_CASE(FB::WindowsEvent, onWindowEvent, FB::PluginWindow) ?第二部份:PPAPI
? Chrome插件只能使用PPAPI接口的Native Client(NaCl)方式編寫,
Native Client分別有三種embed類型
? “application/x-ppapi”,平臺相關,唯一能直接使用win32 api的platfrom(有功能上的限制)。 ?dll格式,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 不允許通過Chrome web store分發。據說Flash就是采用第一種類型開發的。
? “application/x-nacl”, 只能通過PPAPI,平臺無關,cpu相關。nexe格式,只能通過Chrome web store分發。
? “application/x-pnacl”,只能通過PPAPI,平臺無關,cpu無關。pexe格式,可以不通過Chrome web store分發。 ?
? 為了減少麻煩,建議系統只安裝Visual Studo 2010版。
跟著官網先學習第一個PPAPI插件(Native Client)的開發流程
? ?首先參考
? 《C++ Tutorial: Getting Started 》
? https://developer.chrome.com/native-client/devguide/tutorial/tutorial-part1
? 建立,運行,修改自己的第一個portable native client程序,這樣就先有了個概念。
? 按照tutorial一步步走是沒有問題了,但是
? 如何在VS中開發、調試native client程序?
你需要為nacl sdk安裝vs_addin。
官網文檔上說vs_addin只支持vs2010sp1和vs2012,但是經過修改能支持vs2013,但是不建議折騰。[Step1]設置當前計算機用戶變量
? NACL_SDK_ROOT環境變量為“E:\SDK\nacl_sdk\pepper_39”。
? CHROME_PATH環境變量為“C:\Program Files (x86)\Google\Chrome\Application\chrome.exe”。[Step2]管理員權限啟動控制臺轉到“E:\SDK\nacl_sdk\vs_addin”路徑下,輸入“Install”命令安裝“vs_addin”。
? 以后你還可以通過輸入“Install ?--uninstall”命令來反安裝。[FinalStep-PPAPI]現在可以轉到“E:\SDK\nacl_sdk\vs_addin\examples\hello_world_gles”目錄,使用VS2010打開hello_world_gles solution。
? platform從默認“NaCI32”改為“PPAPI”即可編譯通過,會在當前project路徑下產生win目錄,win目錄下會生成hello_world_gles.dll文件。
? 直接按[F5]就可以Debug這個dll,在VisualStudio中進入斷點。[FinalStep-NaCl64]platform從默認“NaCI32”改為“NaCI64”,
? ? ? ? ? project property page should be
? ? ? ? ? [General]->[Native Client]->[IndexPage of NaCl Application]->[index_newlib.html]
? ? ? ? ? [General]->[Native Client]->[Toolchain]->[newlib]
? ? ? ? ? 在當前項目NaCl64\newlib\Debug路徑下只生成一個hello_world_gles_64.nexe文件,所以調試針對的是這個文件。
? ? ? ? ? 由于這個文件是虛擬代碼(據說運行前會轉成機器碼)所以只能用nacl sdk帶的gdb來調試。
? ? ? ? ? [F5]啟動Debug,默認打開index_newlib.html頁面,啟動gdb控制臺后就可以命令行方式調試了。
? ? ? ? ? 你可能需要設置chrome啟用NaCl,授權Chrome能夠使用未經Chrome Web Store發布的nexe文件。[FinalStep-PNaCl]platform從默認“NaCI32”改為“PNaCl”,會在當前項目下編譯輸出一個pexe文件和三個針對不同cpu的nexe文件,VS中[F5]不會進入Debug、break模式。
??
? 備注:
? ?[1]具體參考官方vs-addin文檔。 ?https://developers.google.com/native-client/dev/devguide/devcycle/vs-addin ?
? ?[2]在啟動chrome調試前,勾選F12->Settins->General->Disable cache(while DevTools is open)防止html緩存。
? 如何部署pexe格式控件到chrome上?
[Step1]先檢查PNaCI是否在chrome中啟用(默認已經安裝)
? ? 在chrome中addressbar中使用“chrome://nacl/”查看是否允許PNaCI插件。如果沒有安裝相應component,可以輸入“chrome://components”在compoennts頁面中安裝或更新。
[Step2]假設"E:\nginx-1.8.0\html"是你Web服務器的webroot路徑,把“E:\SDK\nacl_sdk\pepper_39\getting_started\part1”目錄下的
? ? hello_tutorial.nmf和hello_tutorial.pexe兩個文件復制到"E:\nginx-1.8.0\html"。把“index.html”重命名為“hello_tutorial.html”并復制到webroot路徑中。
? ? 現在你的webroot路徑中已經有了“hello_tutorial.nmf”、“hello_tutorial.pexe”和“hello_tutorial.html”三個文件。
[FinalStep]在chorme中輸入“http://localhost:8080/hello_tutorial.html”打開pexe測試頁面,測試成功。
? ? 如何運行vs_addin自帶的hello_nacl_cpp項目?
[Step1]用vs2010打開hello_nacl_cpp項目后,修改好代碼后,選擇PNaCl平臺編譯出pexe和nexe文件。
[Step2]在“E:\SDK\nacl_sdk\pepper_39\examples”路徑下新建“hello_nacl_cpp”目錄。
[Step3]復制“E:\SDK\nacl_sdk\vs_addin\examples\hello_nacl_cpp\hello_nacl_cpp\PNaCl\newlib\Debug”路徑下的pexe、nexe擴展名的四個文件
? ? ? ?到新建的“E:\SDK\nacl_sdk\pepper_39\examples\hello_nacl_cpp”路徑下面。
? ? ? ?復制“E:\SDK\nacl_sdk\vs_addin\examples\hello_nacl_cpp\hello_nacl_cpp\index.html”文件到新的路徑下。
? ? ? ?復制“E:\SDK\nacl_sdk\vs_addin\examples\hello_nacl_cpp\hello_nacl_cpp\PNaCl\hello_nacl_cpp.nmf”文件到新的路徑下。
[Step4]修改新路徑下的index.html,把embed元素中的type屬性從“application/x-nacl”改為“application/x-pnacl”。
? ? ? ?因為PNaCl插件mime type只能為“application/x-pnacl”。
? ? ? ?修改新路徑下的hello_nacl_cpp.nmf文件,使之支持pexe,并能從當前目錄讀取pexe文件,修改后的內容如下:
? ? ? ?{ "files": {}, "program": { ? "portable": { ? ? "pnacl-translate": { ? ? ? "url": "hello_nacl_cpp.pexe" ? ? } ? }, ? "x86-64": { ? ? "url": "hello_nacl_cpp_64.nexe" ? }, ? "arm": { ? ? "url": "hello_nacl_cpp_arm.nexe" ? }, ? "x86-32": { ? ? "url": "hello_nacl_cpp_32.nexe" ? } }}
[FinalStep-PNaCl方式]
? ? ? ?在控制臺下啟動“E:\SDK\nacl_sdk\pepper_39\examples\httpd.cmd”程序。
? ? ? ?在chrome中輸入“http://localhost:5103/hello_nacl_cpp/”成功打開測試頁面。
? ? ? ?如何新建NaCl項目
在visual studio中新建C++ Empty Project
設置項目屬性為[General]->[Project Defaults]->[Configuration Type]->[Dynamic Library(.dll)]。
新建好項目后,就可以添加源代碼文件開始編程。
這里沒有從新的C++ Dll Empty Project開始,是因為這個wizard會引入很多win32定義導致NaCl64平臺編譯失敗,修改起來太麻煩。
示例代碼有兩種風格,第一種參考“vs_addin\examples”下的hello_nacl_cpp項目,第二種參考“hello_world_gles”項目,
開發包自帶的例子基本上都屬于這種風格。
典型的代碼如下:#include "ppapi/cpp/instance.h"#include "ppapi/cpp/module.h"#include "ppapi/cpp/var.h" ?class MyInstance : public pp::Instance {public:?? ?explicit MyInstance(PP_Instance instance) : pp::Instance(instance)?? ?{}?? ?virtual ~MyInstance() {} ??? ?virtual void HandleMessage(const pp::Var& var_message) {?? ??? ?if (var_message.is_string())?? ??? ?{?? ??? ??? ?std::string message = var_message.AsString();?? ??? ??? ?pp::Var var_reply; ??? ??? ??? ?std::string reply = "echo [";?? ??? ??? ?reply.append(message);?? ??? ??? ?reply.append(" from my NaCi module"); ??? ??? ??? ?var_reply = pp::Var(reply);?? ??? ??? ?PostMessage(var_reply);?? ??? ?}?? ?}}; ?class MyModule : public pp::Module {public:?? ?MyModule() : pp::Module() {}?? ?virtual ~MyModule() {}?? ?virtual pp::Instance* CreateInstance(PP_Instance instance) {?? ??? ?return new MyInstance(instance);?? ?}}; ?namespace pp {?? ?Module* CreateModule() {?? ??? ?return new MyModule();?? ?}}
測試dll、pexe格式的控件用的html和js可以從“hello_world_gles”例子的基礎上只要做很小的修改就能測試插件有沒有裝載成功。
“PPAPI”平臺下編譯不會fire load事件在html中,導致不會提示成功裝載插件的提示,但是實際上“hello_world_gles”插件已經正常運行。
你可能需要修改當前工程的[Configuration Properties]->[General]->[Native Client]->[Index Page of NaCl Application]屬性指定html文件名
VS啟動Debug的時候會以命令行方式傳遞給chrome的flags設置。
所以在VS外你要使用nexe文件,需要在Chrome瀏覽器中輸入“chrome://flags/”啟用“Native Client”,授權chrome可以使用未經chrome web store發布的native client程序。
備注:
?[1]NaCl64啟動調試后,在Chrome46中裝載控件會失敗,導致gdb不能單步跟蹤,但是Chrome43沒有這個問題。
[參考資料]
https://developer.chrome.com/native-client/devguide/devcycle/debugging
https://developer.chrome.com/native-client/devguide/devcycle/building ??
? ? 如何在vs2013中使用vs2013的native client插件
[Step1] 復制 %user%\Documents\Visual Studio 2012\Addins\ 到 %user%\Documents\Visual Studio 2013\Addins
[Step2] 復制 ?C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\NaCl\ ?到 ?C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\NaCl\
[FinalStep] 復制 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\ 下的以下文件夾
? ? ?ARM NaCl32 NaCl64 NaClARM PNaCl PPAPI
? ? ?到 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Platforms\
? ? ?
? ? ?C:\Users\kagula\AppData\Local\Google\Chrome\User Data
? ? ?C:\Program Files (x86)\Google\Chrome\Application如何重新編譯NaCi的ppapi_cpp?
打開Visual Studio Command Prompt然后使用下面的命令:
$ cd $NACL_SDK_ROOT\src\ppapi_cpp?
$ make TOOLCHAIN=win CONFIG=Debug?
$ make TOOLCHAIN=win CONFIG=Release NaCl Module如何調用Win32 API?
項目只有在“PPAPI”platform下才能直接調用win32 api,雖然能自由調用win32api,
但是調用win32 api創建新的進程,或調用C++ std對本地磁盤進行操作都會失敗!
想要自由的使用win32 api只能參考下面的文檔來實現,據說是唯一的解決辦法。
《Native Messaging》
https://developer.chrome.com/extensions/nativeMessaging
下面解釋了“PPAPI”platform的限制。
http://stackoverflow.com/questions/23472077/purpose-of-ppapi-toolchain-and-how-to-use-it?rq=1JS如何接收來自Native Client的消息
最簡單的例子是..\nacl_sdk\vs_addin\examples\hello_nacl\hello_nacl下的index.html源文件。常見問題
Q 編譯項目提示。
Error 1?
error MSB6006: "C:\sdk\nacl_sdk\pepper_39\toolchain\win_x86_newlib\bin\x86_64-nacl-g++.exe" exited with code 1.
那是少了依賴庫引起的,比如說,如果你用到gles2,添加“ppapi_gles2”依賴庫后,問題消失。
Q 在“PPAPI”plaform下提示ppapi_cpp.obj找不到。
修改依賴項從“ppapi_cpp;ppapi;”為“ppapi_cpp.lib;ppapi.lib;”后,重新rebuild即可。
Q 運行“...\nacl_sdk\pepper_39\examples”下的例子,chrome提示“PnaclCoordinator: Compile process could not be created”Chrome中輸入“chrome://flags/”,停止“Native Client 基于 GDB 的調試 Mac, Windows, Linux, Chrome OS”項即可。
Q遇到sdk下的examples無法裝載的例子
Chrome中輸入“chrome://components”檢查pnacI是否已經安裝。
總結
? ? 相對于NPAPI,PPAPI開發成本高,運行速度慢,所謂sandbox安全性只不過是始皇上繳天下鐵器的強盜邏輯,
唯一的亮點是PPAPI的pexe格式插件可以一處編譯處處運行。
? ?備注:
[1]在“...\nacl_sdk\pepper_39\examples”路徑下google提供了大量的example用來幫助開發者學習PPAPI。
? ?參考資料[10]也有大量的pexe例子。參考資料
[1]《跨瀏覽器插件框架FireBreath安裝與使用之一——Windows下的插件》
http://blog.csdn.net/ubuntu64fan/article/details/7941167
[2]《Firebreath插件制作》
http://blog.csdn.net/oldmtn/article/details/46362135
[3]FireBreath Home
http://www.firebreath.org/display/documentation/FireBreath+Home
[4]《firebreath 在谷歌和火狐瀏覽器下的調試 以及打包》
http://www.cnblogs.com/drzhong/p/firebreath_dubug.html
[5]《Building a firefox plugin – part one》
http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/
[6]《Introduction to Portable Native Client》
https://www.chromium.org/nativeclient/pnacl/introduction-to-portable-native-client
[7]《Distributing Your Application》
https://developer.chrome.com/native-client/devguide/distributing
[8]《Problems when develop ppapi plugins in NACL.》
https://groups.google.com/forum/embed/#!topic/native-client-discuss/hihnZnB8k0M
[9]《2DPaintingModel》
https://code.google.com/p/ppapi/wiki/2DPaintingModel
[10]《ppapi example》
https://chromium.googlesource.com/chromium/src/ppapi/+/master/examples
---------------------?
作者:kagula086?
來源:CSDN?
原文:https://blog.csdn.net/lee353086/article/details/49302917?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
總結
以上是生活随笔為你收集整理的NPAPI和PPAPI开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jsonp跨域读取cookie
- 下一篇: margin塌陷与margin合并、浮动