NPAPI插件批量注册回调Callback与JS交互,以及回调指针转换

       NPAPI插件是一套老掉牙的chrome浏览器插件环境。很少还有在使用,但是实际要真需要的时候,问题还是要解决的。

       NPAPI插件与JS接口交互+回调交互,一般网上也能找到一些例子,这些例子能解决基本问题。例如实现几个接口+实现几个回调函数与js交互。网上能找到的解决方法有一些弊端。

       缺点一:

       但是当有上百个接口+上百个回调的时候,他们的方法就不好解决问题了。

       缺点二:

       当参数多变的时候问题也不好解决。例如

      图中参数4,直接是一个JS回调函数,这种如何处理,是解决不了的。

解决办法

      怎么创建一个NPAPI插件模板,这里就不介绍了,资源很多。我介绍一下

           1).如何处理大批量的接口+

           2).大批量的回调函数使用+

           3).第三方应用时的奇怪参数转换VARIANT+

1.如何处理大批量的接口

    接口函数入口一般是这样的,包括了字符返回值的转换

    

     如果有100个插件接口都写在这个入口,那真的很难维护,但是如何用一个接口转换把不同接口名,不同参数的接口统一处理了。下面是我的方法。写接口的时候只写一个统一处理接口,

    定义:NPIdentifier m_idCallCplus;

   初始化:m_idCallCplus = NPN_GetStringIdentifier("callCplus");

   接口方法注册:

   方法入口处理:

bool CPluginObject::invoke(NPIdentifier methodName/*调用接口函数名*/,

                                           const NPVariant *args/*接口参数列表*/,

                                           uint32_t argCount/*参数数量*/,

                                           NPVariant *result/*返回值指针*/)
{
    if (methodName == pMe->m_idCallCplus && argCount >= 2/*取最大参数接口参数数量*/ &&     NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) 
    {
        NPString args0 = NPVARIANT_TO_STRING(args[0]);     

        //args[0] 一般设为你的接口识别名字,plugin.callCplus("WEB_getAppDataDir","");
        NPString args1 = NPVARIANT_TO_STRING(args[1]); //第二个参数开始变成你真正需要的参数

        char args0_[1024] = {0};
        char args1_[1024] = {0};
        memcpy(args0_, args0.UTF8Characters, args0.UTF8Length);
        memcpy(args1_, args1.UTF8Characters, args1.UTF8Length);

        //定义一个公共类m_pManager 专门用来处理接口列表
        char* temp = m_pManager->callCplus(args0_, args1_/*针对不同的参数列表,需要定义一个结构来传参数*/);
        NPUTF8* resultVal = static_cast<NPUTF8*>(NPN_MemAlloc(strlen(temp) + 1));
        strcpy(resultVal, temp);
        STRINGZ_TO_NPVARIANT(resultVal, *result);

        return true;
    }

    return false;
}

这样不管有多少接口,多少奇怪的参数都可以以不变应万变,简单处理,贴一下我的处理方式

头文件 QHmanger.h

QHmanger.cpp

2.如何大批量的处理JS的回调函数

需要在插件接口文件plugin.cpp里面实现 Js回调函数指针映射列表,不然是没法被初始化的,我把这个类的写法贴出来,

// pluginCallback  begin/
#include <windows.h>
#include <time.h>

//js回调函数索引

#define  NP_InitSDK_CallIndex                0

第2个

....

第N个

//JS回调注册名字宏定义
#define  NP_InitSDK_CallName                 "WEB_initSDK"

第2个

....

第N个


pluginCallback::pluginCallback()
{
    np_callback.push_back({ NP_InitSDK_CallIndex                , NP_InitSDK_CallName });
第2个

....

第N个

}

pluginCallback::~pluginCallback()
{
    call_back_is_valid_ = false;
    np_callback.clear();
}

//函数指针存入队列
bool pluginCallback::pushCallbackFunc(char* funcName, NPVariant js_in_cb)
{
    bool reged = false;
    for (int i = 0; i < np_callback.size(); ++i)
    {
        if (0 == strcmp(funcName, np_callback[i].call_name))
        {
            NP_Callback cb;
            cb.np_Jscb = (NPVariant)js_in_cb;
            if (np_callback[i].call_backs_list.size() >= 1)
            {
                np_callback[i].call_backs_list[0] = cb;
            }
            else {
                np_callback[i].call_backs_list.push_back(cb);
            }
            reged = true;
        }
    }
    return reged;
}

//获取队列中的对应函数指针
bool pluginCallback::getCallbackFunc(char* funcName, NPVariant& js_out_cb)
{
    bool getcall = false;
    for (int i = 0; i < np_callback.size(); ++i)
    {
        if (0 == strcmp(funcName, np_callback[i].call_name))
        {
            if (np_callback[i].call_backs_list.size() >= 1)
            {
                NP_Callback cb;
                cb = np_callback[i].call_backs_list[0];
                //if (NULL == cb.np_Jscb || call_back_is_valid_ == false) return false;
                js_out_cb = (NPVariant)cb.np_Jscb;
                getcall = true;
            }
            else
                getcall = false;

            break;
        }
    }
    return getcall;
}
// pluginCallback  end/

当然定义了一个回调函数指针映射表,只是第一步,接下来是Js回调函数注册,定义回调执行函数二次转换方法

我们需要定义一个实际执行回调和NPAPI回调转JS的二次转换,因为你直接执行是不行,类型不同牛头不对马嘴。

static void JSCallbackFun(void * oper_func_name, void * param);

把这个新定义的二次转换函数当成指针传给,回调的执行函数。

同样批量处理的第一个函数参数需要是对应的映射表的Js回调名字,说着很复杂,下面会给使用方式,

 

3.奇怪的参数转换

在NPAPI插件里,通用的参数有 “整形”,“double型”,“字符型”,“布尔型”,“Object型”

如果是可以直接当函数数指针传递,但是使用却要转换,像这样

  NPObject *m_JscallbackTmpObj;   //页面函数使用的临时输出回调 指针数组

   plugin->m_JscallbackTmpObj = NPN_RetainObject(NPVARIANT_TO_OBJECT(args[num + 1]));

然后在回调执行函数里找到指针执行。

 

    上面的讲的过于复杂,还是上代码比较直接,代码使用vs2017编译的,只需要看如何用的就行,不用去真的跑起来,安装vs2017也是比较麻烦的。

NPAPI代码:https://download.csdn.net/download/abc1029386453/11465096

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值