PendingVegan
PendingVegan

Reputation: 137

Why does my simple test NPObject not work?

I have this getValue method + NPclass methods:

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;
}

Here are the two other methods the class points to:

 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;
}

Basically, I wanted the object to return 32 when anything was called just to test.

Here are my create & retain methods:

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

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

In my Javascript:

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

The window is drawn on the page, but the console outputs undefined. Help would be greatly appreciated. Thanks!

UPDATE: Georg suggested that the browser was crashing due to infinite recursion with my allocate method. Here is the new one:

 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;
 }

The plugin still crashes.

Update 2: I made the object Instance specific

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

In my NPP_New method I have

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

In my getValue method:

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

still the same problem

Upvotes: 1

Views: 1303

Answers (1)

Georg Fritzsche
Georg Fritzsche

Reputation: 99034

You shouldn't only fill out parts of the NPClass functions, most notably you are missing hasProperty & getProperty. Browsers may handle other missing functions, but as far as i know they are not required to.

Also note that your NPP_GetValue() should only return the scriptable object for variable == NPPVpluginScriptableNPObject.
You should then create scriptable objects per plugin instance (keep in mind that multiple instances of your plugin can run concurrently) and not forget to NPN_Release() the scriptable object when your plugin goes away.
pinvoke() could be improved to:

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;
}

Upvotes: 1

Related Questions