利用NPAPI开发Chrome插件

本文详细介绍如何从Firefox源码中编译NPAPI插件,包括下载SDK、配置VS2008项目、解决编译错误、注册DLL、检测Chrome识别情况及新增接口等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一。编译runtime

1.Download SDK

搜索firefox-4.0.1.source.tar.bz2并下载解压

2.建立工程使用vs2008创建空的win32 dll项目,然后设置工程属性,将firefox-4.0.1.source\mozilla-2.0\modules\plugin\sdk\samples\npruntime存放在工程目录下

步骤一:添加npruntime文件夹下面所有的.h,.cpp文件,还有.rc,.def文件步骤二:工程设置库路径:  工程属性->c/c++常规:附加包含目录   ../../include;../../../../base/public
步骤三:工程设置预处理器:工程属性->c/c++->预处理器:预处理器定义:WIN32;_DEBUG;_WINDOWS;_USRDLL;NPRUNTIME_EXPORTS;XP_WIN32;XP_WIN;_X86_
步骤四:工程设置预编译头:工程属性->c/c++->预编译头:创建/使用预编译头:不使用预编译头
步骤五:建立导出文件声明:def,指定导出接口
步骤六:将.rc文件里面的FileDescrip,fileOpenName,internalName,OrigianalName都改成与工程统一的名称

3.错误解决

开始编译:一堆错误,主要是一下几个error C3861: 'printf': identifier not found 
error C2664: 'DrawTextW' : cannot convert parameter 2 from 'char [128]' to 'LPCWSTR'
error C2275: 'NPPluginFuncs' : illegal use of this type as an expression
error C2065: 'setvalue' : undeclared identifier
error C3861: 'offsetof': identifier not found
第一个错误:plugin.cpp 不认识printf,由于没使用预编译头,因此加上#include <stdio.h>
第二个错误:编译使用的是unicode字符集,因此DrawText会被按照DrawTextW来编译,可以修改工程属性,使用多字符集编译或者将DrawText改为DrawTextA
第三、四五个错误:setvalue offsetoff缺少,加上#include <stddef.h>

4.注册表中注册dll

我电脑是64位系统,在开始--》程序中运行%windir%\SysWOW64\regedit.exe在该路径(计算机\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MozillaPlugins)下添加项(@icbc.com/npNoLogin,ver=1.0.0.1),在该项下新建字符串Path 对应 数值数据C:\Program Files (x86)\ICBCEbankTools\ICBCChromeExtension\npTest.dll

5.检测chrome是否识别

打开chrome浏览器输入chrome::plugins,可以看到该dll的信息在测试页面中修改为
<embed type="application/mozilla-
npruntime-scriptable-plugin" style="display: block; width: 50%; height: 100px;"><br>插件的MIME 类型是application/mozilla-npruntime-scriptable-plugin,fireforx是根据MEMETYPE来加载的。因此需要改成runtime的mime
再次打开,ok,可以点击页面几个按钮感受一下交互例子编译完成,有了初步的认识之后,接下来需要熟悉一下code了。
6.去掉不需要的接口
将plugin.cpp中不需要的接口去掉
bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args,
                               uint32_t argCount, NPVariant *result)
{
    CPlugin * p = (CPlugin *)mNpp->pdata;
   if (!p)
  {
    return false;
  }
   if (name == sFoo_id) {
    printf ("foo called!\n");
    return true;
  }
  return false;

}
此接口修改为
CPlugin::CPlugin(NPP pNPInstance) :
  m_pNPInstance(pNPInstance),
  m_pNPStream(NULL),
  m_bInitialized(false),
  m_pScriptableObject(NULL)
{
  m_pNPInstance->pdata = this;
#ifdef XP_WIN
  m_hWnd = NULL;
#endif
  NPN_GetValue(m_pNPInstance, NPNVWindowNPObject, &sWindowObj);
}
7.新加接口
在plugin.cpp中添加
步骤一:static NPIdentifier  s_idGetVersion;
步骤二:在CPlugin的构造函数中添加
 s_idGetVersion  = NPN_GetStringIdentifier("getVersion");
步骤三:在bool
ScriptablePluginObject::HasMethod(NPIdentifier name){}中添加
 if(name == s_idGetVersion)
 {
  return true;
 }
步骤四:在Invoke方法中添加
  else if(name == s_idGetVersion)
  {
 NPUTF8 *pVersionTemp=p->getVersion();
 int32_t iLen=strlen(pVersionTemp);
 NPUTF8 *strVersion = (NPUTF8 *)NPN_MemAlloc(iLen*sizeof(NPUTF8)+32);//分配内存适当大一些
 strcpy_s(strVersion,iLen*sizeof(NPUTF8)+32,pVersionTemp);  
 STRINGZ_TO_NPVARIANT(strVersion,*result);
 return true;
  }
步骤五:在测试页中添加
<object id="embed1" type="application/npTest-plugin" width=600 height=40><br>
</object>

<br>
<form name="formname">
<br>
<input type=button value="GetVersion" onclick=getV()>
</form>
<script language="javascript">
function getV()
{
 var strVersionText1 = embed1.getVersion();
 console.log("VersionInfo:\0" + strVersionText1); 
}
</script>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值