【问题标题】:Trouble loading an NPAPI plugin in Mac app在 Mac 应用程序中加载 NPAPI 插件时遇到问题
【发布时间】: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


【解决方案1】:

我假设你不使用这个 UI 线程,如果你确实在不同的线程中尝试你的代码,如果是这样的话。但是,它可能与很多事情有关,从图像本身开始(因为它是空的/透明的),这是我使用的:

UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); //after this you should see the image

以下cmets与Mozilla CoreAnimationDrawingModel plugin相关

(你的黑盒插件可能是基于它的?)

确保您使用 Flash 10.1+,因为该版本之前不支持 Core Animation 绘图模型(您加载了 SWF)。

注意!如果你的黑盒插件使用 QTMovieLayer 渲染它应该会失败,因为它不受 renderInContext 支持。

关于您的主题的其他有趣阅读(从 2010 年开始):Core Animation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多