В комментариях нет места, чтобы хорошо ответить на ваш вопрос в комментарии, поэтому я добавлю его в другой ответ.
Каждый раз, когда ваш код получает NPObject от функции NPObject (одной из тех, что вы упомянули выше), вы должны освободить этот NPObject, когда закончите с ним. (это может быть немедленно, или вы можете сохранить его на некоторое время и отпустить, когда ваш объект будет уничтожен). То же самое относится и к NPVariant. не сохраняется с аргументами, передаваемыми в вашу функцию Invoke, но заданное вами возвращаемое значение будет выпущено браузером, когда это будет сделано.
Когда вы вызываете NPN_GetValue и получаете оттуда NPO-объект, он также должен быть освобожден. Это означает, что когда браузер вызывает NPP_GetValue, он выпустит ваш NPObject, когда это будет сделано. Если вы хотите создавать новый NPObject каждый раз, когда браузер вызывает NPP_GetValue, чтобы получить ваш NPObject, то вам не нужно вызывать NPN_RetainObject для него; в примере NPAPI предполагается, что вы сохраняете копию вашего NPObject, чтобы он не удалялся до тех пор, пока не будет удален ваш объект плагина.
Поскольку браузер будет вызывать Release каждый раз, когда он вызывает NPP_GetValue, чтобы получить ваш NPObject, вам необходимо убедиться, что refcount увеличивается, прежде чем вы его вернете. Причина, по которой вам не нужно вызывать его дважды в случае, если вы собираетесь его сохранить, заключается в том, что NPN_CreateObject выполняет неявное сохранение, прежде чем оно возвращает ваш объект.
Я написал более подробное объяснение здесь: