2

我对 npapi 中的引用计数感到困惑。大多数情况下,我不知道哪种方法会增加引用计数。谁能详细解释一下?为方便起见,我在这里列出了最常用的 NPN_* 函数以及我自己的理解:

NPN_CreateObject:将引用计数设置为 0

NPN_RetainObject:增加引用计数

NPN_ReleaseObject:十进制引用计数

NPN_Evaluate: ?? (如果返回一个 NPObject*)

NPN_GetValue: ?? (如果返回一个 NPObject*)

NPN_SetValue: ?? (如果设置为 NPObject*)

NPN_GetProperty: ?? (如果返回一个 NPObject*)

NPN_SetProperty: ?? (如果设置为 NPObject*)

NPN_RemoveProperty: ??

NPN_Enumerate: ??

NPN_Construct: ??

另一件事:npapi 是做嵌套发布吗?(如果 NPObject* 具有 NPObject* 的属性,释放父级将减少子级的引用计数)。

谢谢。

4

2 回答 2

4

评论中没有空间可以很好地回答您在评论中的问题,因此我将其放在另一个答案中。

每当您的代码从 NPObject 函数(您上面提到的函数之一)获取 NPObject 时,您应该在完成后释放该 NPObject。(这可能是立即的,或者您可以将其保存一段时间并在您的对象被破坏时释放它)。NPVariant 也是如此。它不适用于传递给 Invoke 函数的参数,但您设置的返回值将在完成后由浏览器释放。

当您调用 NPN_GetValue 并从那里获取一个 NPObject 时,它也必须被释放。这意味着当浏览器调用 NPP_GetValue 时,它​​会在完成后释放你的 NPObject。如果您想在每次浏览器调用 NPP_GetValue 来获取您的 NPObject 时创建一个新的 NPObject,那么您不必在其上调用 NPN_RetainObject;NPAPI 示例中的假设是您正在保存 NPObject 的副本,以便在您的插件对象被删除之前它不会被删除。

由于浏览器每次调用 NPP_GetValue 来获取您的 NPObject 时都会调用 Release,因此您需要确保在返回它之前增加引用计数。如果您要保留它,您不必调用它两次的原因是 NPN_CreateObject 在返回您的对象之前会执行隐式保留。

我在这里写了更详细的解释:

于 2009-12-24T19:56:12.847 回答
3

首先,纠正一个误解:NPN_CreateObject 将 refCount 设置为 1,而不是 0。然后,当您调用 NPN_RetainObject 时,它会增加 refcount,而 NPN_ReleaseObject 会减少它。如果 ReleaseObject 将 refcount 减为 0,它还将通过调用 NPClass 中的 deallocate 函数来释放它(在进行任何需要的清理后应该删除 NPObject)

见:https ://developer.mozilla.org/En/NPClass

除此之外,任何其他 NPClass 函数的一个好的一般经验法则是,任何时候将 NPObject 放入 NPVariant 中,都需要调用 NPN_RetainObject。要记住这一点,只需记住当您使用 NPVariant(您已经使用并已完成,而不是作为返回值传递的)时,您调用 NPN_ReleaseVariantValue,如果它是一个,它将释放 NPString 数据字符串或 NPObject(如果它是对象)。

因此,从任何其他方法中,如果要返回 NPObject,则需要在将其填充到 NPVariant 之前调用 NPN_RetainObject。此外,如果您保存 NPObject 的副本,则应在其上调用 NPN_RetainObject 并在保存完成后调用 NPN_ReleaseObject。还值得一提的是,您永远不应该从主线程以外的线程调用任何 NPN_ 方法。

这有帮助吗?

于 2009-12-24T17:48:57.927 回答