【发布时间】:2015-08-10 21:24:08
【问题描述】:
我正在开发一个独立的守护程序可执行文件,它需要在主机上加载现有的第三方 NPAPI 插件。我想要做的是将插件生成的视图渲染到纹理/表面。
它需要同时在 Mac 和 Windows 上运行,但由于我是一个重度 Mac 用户,我决定先构建 Mac 版本。我们没有这个插件的源代码——它是外部供应商提供给我们的——所以它是一个黑盒实现。
在网络上,该插件的工作方式与 Flash 非常相似。您在链接到特定 mimetype(即应用程序/flash)的网页中嵌入了一个区域并加载插件,这反过来将指示插件加载特定文件(想想 SWF)然后呈现它。
我现在正在做的是:
1. Open the library (Bundle) and extract NP_Initialize etc.
2. Call NP_Initialize -> returns the object with NPP function pointers etc
3. Call NPP_New (this calls a set of NPP functions) -> ultimately returns NPERR_NO_ERROR.
由于 NPERR_NO_ERROR 是预期的响应,我假设这三个步骤已成功完成。
在 NPP_New 期间,插件请求 Cocoa 事件模型和核心动画(或者,如果我为核心动画返回 false,则请求核心图形)渲染模式。
然后我打电话:
4. NPP_SetWindow
5. Once the window is set, I load an online file with CURL, and call NPP_NewStream/WriteReady/Write and DestroyStream.
从我在 NPAPI 文档中可以找到的内容来看,NewStream/WriteStream/etc 函数基本上将文件加载到插件的内存中,因此可以渲染它。
该插件在浏览器中同时支持 Core Animation 和 Core Graphics,并且在支持 NPAPI 插件的浏览器中运行良好。
完成上述所有操作后,我尝试渲染到纹理,但在核心图形模式下,我不断收到来自带有 CGContextRef 的 NPP_Event 函数调用的错误响应。在核心动画模式下运行时,我使用 renderInContext 将纹理渲染为位图,但整个图像保持空白/透明。
这是一个很长的镜头,但有人有什么想法吗?
【问题讨论】:
-
插件是否有其他调用进入您的“页面”?您是否从插件中调用并请求根 NPObject?插件可能有一些您尚未提供的东西
-
如何确定我需要为插件提供什么?在 NPP_New 期间,从“假”浏览器中的插件(一些 Get/SetValue、Invoke、Evaluate)调用了大量 NPN 函数。我根据我对需要返回什么的最佳猜测返回 NPObjects。经过反复试验(如果返回的对象类型不正确,插件将关闭),NPP_New 最终返回 NO_ERR。我没有从插件调用根 NPObject(尽管插件在 NPP_New 期间确实从浏览器请求根 NPObject)。但是我会用那个对象做什么呢?
-
好的,我已经设置了代理插件记录器。通过 Firefox 加载插件时,在 NPP_New 成功返回 NO_ERR 后,似乎收到了 NPN_GetURLNotify 事件。但是,我的 C++ 应用程序从未收到此消息。我是否需要设置线程或事件循环或其他东西来捕获它?
-
很难说;很可能是这些调用的结果不是插件所期望的,因此它不能正常工作
-
NPAPI 指定不当;一般来说,对浏览器所做的事情进行逆向工程,然后自己做是实现主机的唯一方法。不同的插件隐含地依赖于最初可能是一个浏览器的怪癖的特定行为,但现在必须在任何地方复制(例如,Mac 上的 QuickTime 插件需要以特定顺序完成初始化调用,即使基本上没有其他插件这样做)。
标签: cocoa plugins webkit npapi gecko