为什么我的简单测试NPObject不起作用?

时间:2012-07-25 23:34:20

标签: npapi browser-plugin npruntime

我有这个getValue方法+ NPclass方法:

static bool hasmethod(NPObject *npobj, NPIdentifier name)
{
    return true;
}
static NPObject* allocate (NPP npp, NPClass *aClass)
{
    return  browser-> createobject(npp, aClass);
}
static bool hasProperty(NPObject *npobj, NPIdentifier name)
{
     return true;
}
static bool getProperty (NPObject *npobj, NPIdentifier name, NPVariant *result)
{
   if (!result) 
       return false;
   INT32_TO_NPVARIANT(50, *result);
   return true;
}
static void deallocate (NPObject *npobj)
{
   browser -> memfree(npobj);
}
static bool enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
{
    return false;
}
static bool defaultInvoke(NPObject* obj, const NPVariant *args, uint32_t argCount,     NPVariant *result)
{
    if (!result) 
    return false;
    INT32_TO_NPVARIANT(42, *result);
    return true;
}
static bool setProperty (NPObject *npobj, NPIdentifier name, const NPVariant *value)
{
    return false;
}  
static void invalidate(NPObject *npobj)
{
}
static bool removeProperty (NPObject *npobj,NPIdentifier name)
{
    return false;
}
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
    if (! instance)
    {
        return NPERR_INVALID_INSTANCE_ERROR;
    }
struct NPClass class;
class.structVersion = NP_CLASS_STRUCT_VERSION;
class.construct = NULL;
class.deallocate = deallocate;
class.hasMethod = hasmethod;
class.getProperty= getProperty;
class.enumerate= enumerate;
class.removeProperty= removeProperty;
class.hasProperty = hasProperty;
class.invoke = pinvoke;
class.invokeDefault = defaultInvoke;
class.invalidate = invalidate;
class.setProperty = setProperty;
class.allocate = allocate;
if (variable == NPPVpluginScriptableNPObject)
{
    void **v = (void **)value;
    struct NPObject *object = NPN_CreateObject(instance, &class);
    NPN_RetainObject(object);
    *v = object;
    return NPERR_NO_ERROR;
}
return NPERR_GENERIC_ERROR;
}

以下是该课程指向的另外两种方法:

 bool hasmethod(NPObject *npobj, NPIdentifier name)
 {
     return true;
 }

static bool pinvoke(NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
    if (!result) 
    return false;
    INT32_TO_NPVARIANT(32, *result);
    return true;
}

基本上,我希望对象在调用任何东西时返回32只是为了测试。

这是我的创作&保留方法:

NPObject *NPN_CreateObject(NPP npp, NPClass *aClass)
{
    return browser->createobject(npp, aClass);
}

NPObject *NPN_RetainObject(NPObject *npobj)
{
    return browser->retainobject(npobj);
}

在我的Javascript中:

        <embed type="application/x-my-extension" id="pluginId">
            <script>
            var plugin = document.getElementById("pluginId");
            console.log(plugin.something);

窗口在页面上绘制,但控制台输出未定义。 非常感谢帮助。谢谢!

更新:Georg建议浏览器由于我的allocate方法无限递归而崩溃。这是新的:

 void* NPN_MemAlloc(uint32_t size)
 {
     return browser->memalloc(size);
 }
 static NPObject* allocate (NPP npp, NPClass *aClass)
 {
   NPObject* object = (NPObject*)NPN_MemAlloc(sizeof(NPObject));
   if (!object)
   {
    return NULL;
   }
   memset(object, 0, sizeof(NPObject));
   return object;
 }

该插件仍然崩溃。

更新2:我使对象特定于实例

typedef struct PluginInstance {
  NPP npp;
  NPWindow window;
  NPObject *object;
}PluginInstance;

在我的NPP_New方法中我有

 PluginInstance *newInstance = (PluginInstance*)malloc(sizeof(PluginInstance));
 bzero(newInstance, sizeof(PluginInstance));
 newInstance -> object = NPN_CreateObject(instance, &class);
 newInstance->npp = instance;
 instance->pdata = newInstance;

在我的getValue方法中:

    NPObject* obj = ((PluginInstance *) (instance->pdata)) -> object;
    void **v = (void **)value;
    NPN_RetainObject(obj);
    *v = obj;

仍然是同样的问题

1 个答案:

答案 0 :(得分:1)

您不仅应该填写NPClass部分功能,最明显的是您缺少hasProperty&amp; getProperty。浏览器可以处理其他缺失的函数,但据我所知,它们不是必需的。

另请注意,您的NPP_GetValue()应仅返回variable == NPPVpluginScriptableNPObject的可编写脚本的对象 然后,您应该为每个插件实例创建可编写脚本的对象(请记住,插件的多个实例可以同时运行)并且在插件消失时不要忘记NPN_Release()脚本化对象。
pinvoke()可以改进为:

static bool pinvoke(NPObject* obj, NPIdentifier methodName, const NPVariant *args, 
                    uint32_t argCount, NPVariant *result)
{
    if (!result) 
        return false;
    INT32_TO_NPVARIANT(32, *result);
    return true;
}