在C#中构建NPAPI插件

6
尝试构建一个C# NPAPI插件时,我发现教程描述了你的dll需要实现一些方法,如NP_GetEntryPointsNP_InitializeNPP_New,以及其他一些方法。
然而,我想知道的是,如果我能够简单地模仿这些方法名称,并按照文章中描述的构造等效的数据结构(如_NPPluginFuncs),是否可以使一切正常工作呢?
请问有人能够提供一些指导吗?是否有可能在C#中构建NPAPI插件,如果可以,涉及哪些基本步骤?

3
我无法就NPAPI的细节问题给你详细的回答,但一般而言,使用C#创建一个带有C兼容导出函数的DLL是不可能的。你可以选择:1)创建混合模式的C++ DLL,或者(如果你比较熟悉C#而不是托管的C++)2)创建一个小型的本地DLL来包含你的导出函数,然后使用COM互操作委托到一个由C#编写的托管程序集,该程序集包含了大部分的功能。 - anton.burger
现在这基本上就是一个答案。我认为在最差的情况下可能会有某种类型的互操作性(虽然不了解足够的C++以假定COM),但我也想到了在C++和C#之间实现互操作的更简单的方法。 - Maxim Gershkovich
P/Invoke 很棒,但是反向互操作仍然很痛苦,我很抱歉 :P - anton.burger
1
这里有一个看起来很有趣的项目链接,如果你不介意依赖的话,它可以让生活变得更加轻松。 - anton.burger
@shambulator:你应该将这些注释移动到一个答案中(NPAPI插件基本上是带有几个必需的C导出函数的DLL)。 - Georg Fritzsche
1
有没有办法在这些答案之间分配赏金?不确定哪一个是正确的。谢谢你们两个! - Maxim Gershkovich
2个回答

4

根据文档所述:

NPAPI浏览器插件本质上只是带有几个特定入口点的DLL。

这意味着您需要从常规dll中导出一些函数,通常使用C/C++完成。不幸的是,无法从纯C# dll中公开任何入口点,但请看这个答案,通过某种后期构建工具的努力,似乎可以欺骗一些导出。

无论如何,不要指望从/到插件接口传递过于复杂的数据结构,这将很痛苦。如果您有兴趣进行更多研究,则需要使用关键字"reverse P/Invoke",类比于直接P/Invoke,即从托管世界调用常规dll。

C# dll无法直接公开“入口点”的原因是,入口点实际上只是指向某些可立即执行的程序集代码的dll内部地址。 C# dll是不同类型的文件:它们只包含IL代码,这些代码是“即时编译”的,并且我所知道的确实强制进行了这种编译通过一些操作系统技巧。这就是为什么反向P / Invoke并不简单的原因。

这实际上是让我困惑的确切陈述:“一个 NPAPI 浏览器插件在其核心就是一个带有几个特定入口点的 DLL”。我的第一反应是“太好了,那么我可以用 C# 来编写它”,我猜我从来没有真正考虑过 DLL 如何实现“入口点”,并且一直认为 C++ 和 C# 中的“入口点”会起到相同的作用。回想起来是一个愚蠢的想法,但我从未写过一行 C++ 代码。 - Maxim Gershkovich
谢谢,我感谢您的澄清。 - Maxim Gershkovich

4
正如Georg Fritzsche在他的评论中所说:
NPAPI插件基本上是带有一些必需的C导出函数的DLL
而从C#编写的程序集中没有内置的方法来导出函数(以C导出的意义)。
您的一些选项包括:
1.混合模式C++程序集,可以直接导出函数。这可能会对在插件宿主进程中托管CLR产生影响。
2.一个小型本地DLL,用于托管导出,然后使用COM互操作委托到包含插件功能的C#程序集。所谓的“反向p/invoke”的“官方”方式。
3.一个有趣的项目,它对完全托管的程序集进行后处理,将标有自定义属性的静态方法转换为命名函数导出。(我与此项目无关;在我想知道是否有人改进了COM互操作方式之后,我偶然发现了它。)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接