когда выпустить объект в плагин npapi - PullRequest
2 голосов
/ 23 декабря 2009

Я запутался по поводу количества ссылок в npapi. В основном, я не знаю, какой метод увеличит количество ссылок. Кто-нибудь может объяснить подробно об этом? Для удобства я перечислил наиболее часто используемые функции NPN_ * здесь и мое собственное понимание:

NPN_CreateObject: установить счетчик ссылок на 0

NPN_RetainObject: счетчик ссылок

NPN_ReleaseObject: dec ref count

NPN_Evaluate: ?? (в случае возврата NPObject *)

NPN_GetValue: ?? (в случае возврата NPObject *)

NPN_SetValue: ?? (в случае, если установлен NPObject *)

NPN_GetProperty: ?? (в случае возврата NPObject *)

NPN_SetProperty: ?? (в случае, если установлен NPObject *)

NPN_RemoveProperty: ??

NPN_Enumerate: ??

NPN_Construct: ??

Другое дело: npapi делает вложенный выпуск? (В случае если NPObject * со свойством NPObject *, родительский релиз уменьшит количество ссылок на дочерние элементы).

Спасибо.

Ответы [ 2 ]

4 голосов
/ 24 декабря 2009

В комментариях нет места, чтобы хорошо ответить на ваш вопрос в комментарии, поэтому я добавлю его в другой ответ.

Каждый раз, когда ваш код получает 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 выполняет неявное сохранение, прежде чем оно возвращает ваш объект.

Я написал более подробное объяснение здесь:

3 голосов
/ 24 декабря 2009

Во-первых, чтобы исправить ошибочное представление: NPN_CreateObject устанавливает refCount в 1, а не в 0. Затем, когда вы вызываете NPN_RetainObject, он увеличивает refcount, а NPN_ReleaseObject будет уменьшать его. Если ReleaseObject уменьшает refcount до 0, он также освобождает его, вызывая функцию deallocate из вашего NPClass (который должен удалить NPObject после выполнения любой необходимой очистки)

см .: https://developer.mozilla.org/En/NPClass

кроме того, хорошее общее правило для любой из других функций NPClass заключается в том, что каждый раз, когда вы помещаете NPObject в NPVariant, вам необходимо вызывать NPN_RetainObject. Чтобы запомнить это, просто помните, что когда вы закончите с NPVariant (тот, который вы использовали и сделали, а не тот, который был передан в качестве возвращаемого значения), вы вызываете NPN_ReleaseVariantValue, который освободит данные NPString, если это строка или объект NPO, если это объект.

Так что из любого другого метода, если вы возвращаете NPObject, вам нужно вызвать NPN_RetainObject, прежде чем вставить его в NPVariant. Кроме того, если вы сохраняете копию NPObject, вы должны вызвать NPN_RetainObject для нее и NPN_ReleaseObject, когда вы закончите ее сохранение. Также стоит упомянуть, что вы никогда не должны вызывать какой-либо метод NPN_ из потока, отличного от основного потока.

Это помогает?

...