在 C# 中构建 NPAPI 插件

Posted

技术标签:

【中文标题】在 C# 中构建 NPAPI 插件【英文标题】:Building NPAPI plugin in C# 【发布时间】:2012-07-03 10:33:15 【问题描述】:

尝试构建 C# NPAPI 插件我发现了一个tutorial,它描述了您的 dll 需要实现许多方法,例如 NP_GetEntryPointsNP_InitializeNPP_New 以及其他一些方法。

但是我想了解的是,如果我可以简单地镜像这些方法名称并在 C# 中构建文章中描述的等效数据结构(如_NPPluginFuncs),那么一切都会正常工作吗?

有人可以提供一些指导吗?是否可以,如果可以,涉及的基本步骤是什么?

【问题讨论】:

我不能具体给你一个关于NPAPI的详细答案,但总的来说,使用C#创建一个与C兼容的导出函数的DLL是不可能的。您可以 1)创建一个混合模式 C++ DLL,或者(如果您更熟悉 C# 而不是托管 C++)2)创建一个包含导出的小型本机 DLL,它使用 COM 互操作委托给编写的托管程序集在 C# 中,其中包含您的大部分功能。 现在这基本上是一个答案。我认为在更糟糕的情况下,某种类型的互操作是可能的(尽管对 C++ 的了解不足以假设 COM),但我也认为 C++ 和 C# 之间的互操作会有一条更简单的路径 P/Invoke 很棒,但另一个方向的互操作仍然很痛苦,恐怕:P 看起来很有趣的项目here,如果你不介意依赖它,它可以让生活变得更轻松。 有没有办法在这些答案之间分配赏金?不确定要标记哪一个正确。谢谢你们! 【参考方案1】:

如文档中所述:

NPAPI 浏览器插件的核心只是一个带有几个特定入口点的 DLL

这意味着您需要从常规 dll 中导出一些函数,这通常在 C/C++ 中完成。不幸的是,不可能从普通的 C# dll but look at this answer 公开任何入口点,通过某种后期构建工具似乎可以欺骗某些导出。

在任何情况下都不要期望从/到插件接口传递太多复杂的数据结构,这会很痛苦。如果您有兴趣进行更多研究,则使用的关键是“反向 P/Invoke”,类似于从托管世界调用常规 dll 的直接 P/Invoke。

C# dll 不能直接公开“入口点”的原因是,入口点实际上只是 dll 内的某个地址,指向一些可立即执行的汇编代码。 C# dll 是另一种野兽:它们只是包含“及时”编译的 IL 的文件,实际上这种编译是强制的 AFAIK with some OS tricks。这就是反向 P/Invoke 根本不简单的原因。

【讨论】:

这实际上是让我感到困惑的确切陈述“NPAPI 浏览器插件的核心是一个带有几个特定入口点的 DLL” - 我的第一个想法是“太好了,所以我可以写这个在 C# 中”我想我从来没有真正考虑过 DLL 如何实现“入口点”,并且一直认为 C++ 和 C# 中的“入口点”会工作相同。回想一个愚蠢的想法,但我从未写过一行 C++ 谢谢您的澄清。【参考方案2】:

正如 Georg Fritzsche 在他的评论中所说:

NPAPI 插件基本上是带有一些必需的 C 导出的 DLL

并且没有内置方法可以从用 C# 编写的程序集中导出函数(在 C 导出意义上)。

您的一些选择是:

    可以直接导出函数的混合模式 C++ 程序集。这可能会对在插件的宿主进程中托管 CLR 产生影响。 托管导出的小型本地 DLL,然后使用 COM 互操作委托给包含插件功能的 C# 程序集。执行所谓“反向 p/invoke”的“官方”方式。 intriguing project 对您的完全托管程序集进行后处理,将标有自定义属性的静态方法转换为命名函数导出。 (我与这个项目没有任何关系;在我想知道是否有人改进了 COM 互操作的做事方式后,我偶然发现了它。)

【讨论】:

谢谢,这深入探讨了我实际上在问但不知道如何表达的问题。

以上是关于在 C# 中构建 NPAPI 插件的主要内容,如果未能解决你的问题,请参考以下文章

从 Firefox 扩展调用 NPAPI 插件功能

仅使用 Firefox Addon SDK 在后台嵌入 NPAPI 插件

从 NPAPI 插件中启动外部应用程序

QWebkit无法检测NPAPI插件

NPAPI 插件未在 Firefox 中加载

Chrome禁用NPAPI插件(包含 SilverlightJava 和 Unity)