编写、加载和存取插件程序(Plug-Ins)

在 2005 年一月刊的 MSDN 杂志文章中,你有一个例子程序的代码是用混合模式编写的。有没有可能动态加载 .NET 类或 DLL 并调用那些函数呢?假设我有一个本机 C++ 应用程序,我想允许用户在 .NET 中为该 C++ 程序编写插件。就像在 .NET 中使用 LoadLibrary 加载 DLLs 一样。

Ravi Singh

我正在用 Visual C++ 6.0 编写一个插件应用,它是一个 DLL,输出和接收纯虚拟接口指针。加载 DLL 后,EXE 便调用 DLL 中输出的 C 函数,该函数返回一个纯虚拟接口指针。然后 EXE 调用该接口上的方法,有时会传回另一个接口指针给 DLL 处理。

目前有人要求必须用 C#,Visual Basic .NET 和其它语言编写插件。我没有什么基于 .NET 的编程经验,不懂托管和非托管代码之间的通讯问题,我找到许多有关这方面的信息,但是越看越糊涂。我如何才能让用户编写基于.NET 语言的插件? 

Daniel Godson

在 MSDN 杂志 2003 年 10 月刊中,有一篇 Jason Clark 写的一篇关于插件的文章,但我并不介意在此复习一下这个主题,尤其是因为插件本身就是 .NET 框架中举足轻重的部分(参见:Plug-Ins: Let Users Add Functionality to Your .NET Applications with Macros and Plug-Ins)。毕竟,微软 .NET 框架的主要目的之一就是为编写可重用的软件组件提供一种语言无关的系统。从第一个 “Hello,world”程序到现在,这已经成为软件 开发至高无上的准则。可重用性从拷贝/粘贴到子例程,再到静态链接库,再到 DLLs 以及更专业的 VBX,OCX 和 COM。虽然最后三个东西属于不同的主题(它们都是 本机 DLLs),.NET 框架标志着一个真正的开端,因为所有代码都被编译成微软中间语言(MSIL)。互用性成为一种不可或缺的成分,因为在公共语言运行时层面,所有代码都一样。这就使得编写支持语言中立的插件体系结构 的程序变得尤其容易。

那么在你的 C++ 程序中如何利用这个优势呢?Daniel 的虚拟函数指针系统就是一个手工自制的 COM。它就是 COM 对象本质之所在:纯虚拟函数指针。你可以为插件模型使用 COM ,开发人员可以用任何面向 .NET 的语言编写插件,因为这个框架让你创建和使用 COM 对象。但众所周知, COM 编码非常繁杂,因为它需要考虑的细节颇多,例如注册、引用计数,类型库等等——这些东西足以使你认为 COM 简直就是“Cumbersome Object Model”(麻烦对象模型)。如果你正在编写新代码并试图简化你的日常工作,那么就用 .NET 直接实现一个插件模型吧,我现在就是在讨论这个话题。

首先让我回答 Ray 的问题,即:在 .NET 中有没有类似 LoadLibrary 的东西,答案是:有,你可以用静态方法 System::Assembly::Load 加载任何框架程序集(就是一个包含 .NET 类的 DLL)。此外,.NET 支持反射机制。每个程序集都提供所有你需要的信息,如:该程序集有什么类,什么方法以及何种接口。不需要关心 GUIDs,注册,引用计数等诸如此类的事 情。

在我展示更一般的插件系统之前,我将从一个简单的例子开始,Figure 1 是一个 C# 类,它提供一个静态函数 SayHello。注意与 C/C++ 不同,在 .NET 中函数不单独输出;每个函数必须属于某个类,虽然这个类可以为静态的,也就是说它不需要实例化。为了将 MyLib.cs 编译成一个库,可以这样做:csc /target:library MyLib.cs

编译器将产生一个名为 MyLib.dll 的 .NET 程序集。为了通过托管扩展从 C++ 中调用 SayHello,你得这样写:

#using <mscorlib.dll>
#using <MyLib.dll>
using namespace MyLib;
void main ()
{
  MyClass::SayHello("test1");
}

编译器链接到 MyLib.dll 并调用正确的入口点。这一切都简单明了,它属于 .NET 的基础。现在假设你不想在编译时链接 MyLib,而是想进行动态链接,就像在 C/C++ 用 LoadLibrary 那样。毕竟,插件无非是要在运行时链接,在你已经生成并交付的应用程序之后。Figure 2 所做的事情和前述代码段一样,只不过它是动态加载 MyLib 的。关键函数是 Assembly::Load。一旦你加载了该程序集,你便可以调用 Assembly::GetType 来获得有关类的 Type 信息(注意你必须提供全限定名字空间和类名),进而调用 Type::GetMethod 来获取有关方法的信息,甚至是调用它,就像这样:

MethodInfo* m = ...; // get it
String* args[] = {"Test2"};
m->Invoke(NULL, args);

时间: 2024-08-22 07:21:19

编写、加载和存取插件程序(Plug-Ins)的相关文章

浏览器--internet选项--程序--管理加载项中的加载项与插件是一个概念吗,有什么区别?

问题描述 问题一:浏览器--internet选项--程序-管理加载项中的加载项与插件是一个概念吗,有什么区别?问题二:我用360安全卫士的清理插件功能,找出的插件数量为什么远多于浏览器--internet选项--程序里的加载项啊?

C#如何卸载dll插件,将加载好的插件实现卸载,用什么方法,求大神指导给个示例

问题描述 C#如何卸载dll插件,将加载好的插件实现卸载,用什么方法,求大神指导给个示例 我现在只会用 assembly 反射加载插件,就不不知道卸载的方法,网上说的太深奥,求大神具体指导下,给个示例代码 解决方案 据我所知,插件没有办法卸载.如果你说的卸载只是为了使得用户可以删除插件文件的话,那么可以用assembly.loadfrom(filestream)的方式加载,而不是直接从文件加载. 这样插件dll可以在程序运行的时候被删除.但是这不是卸载,你的主程序还是可以继续调用这个插件. 你可

jquery 预加载图片效果插件与实例

文章一款告诉你如何利用jquery 预加载图片的实例教程,同时你也可以根据它出制作出漂亮的jquery 预加载图片效果哦. <!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/x

请问怎么在程序中以对话框的形式加载另一个exe程序

问题描述 请问怎么在程序中以对话框的形式加载另一个exe程序 请问怎么在程序中以对话框的形式加载另一个exe程序,同时怎么把这个程序中的数据发送到那个程序里,谢谢 解决方案 用shellexecute载入你的程序,用setparent设置程序的父窗体为你的窗体. 解决方案二: 用这个java为例子吧 首先你要做这个swing界面的对话框 (不会可以看看对话框打开的方法 swing ) 第二部你然后通过对话框去选择你的exe程序 这个时候把这个exe当文件看待 第三步是重点了: 如何执行程序 Ru

VS2008中加载了2005的程序,但是会出现ajax的错误,怎么在2008里设置2.0环境?

问题描述 如题,就是2008已经加载了2005的程序,好像改成了3.5环境了,但是现在想改为2.0,怎么设置? 解决方案 解决方案二:首先在SolutionExplorer选中你的project:View-->propertypages(Shift+F4)-->Build-->TargetFramework下拉选取项,选择.NETFramework2.0解决方案三:我用2008已经把项目打开了,在View里没有propertypages啊,只有propertieswindow解决方案四:

JS实现的自定义显示加载等待图片插件(loading.gif)_javascript技巧

本文实例讲述了JS实现的自定义显示加载等待图片插件.分享给大家供大家参考,具体如下: 在工作中遇到了一个问题 -- 某个业务流程分为几个阶段,每个阶段如果在数据没有显示出来之前就要显示加载图片loading.gif文件,如果有数据了就消失.为此,自己写了一个方法,方便整个工程使用. <button onclick="show()">show</button> <button onclick="hide()">hide</bu

listview分组加载怎么自动对程序进行分类呢?

问题描述 listview分组加载怎么自动对程序进行分类呢? 根据图标的种类对图标方式进行分类,listview分组加载怎么自动对程序进行分类呢? 解决方案 可以通过程序版本信息对程序分类,用getversionex函数获得版本信息. 解决方案二: ListView分类加载

自己动手制作基于jQuery的Web页面加载进度条插件_jquery

静态效果的实现 网页顶部加载进度条,近年来很流行,很多网站都采用了这种加载方式.网上也有这样类似的插件,今天我们总结一下网页顶部线性页面加载进度条. 大体的写法如下: body{ margin:0; } #progress { position:fixed; height: 2px; background:#2085c5; transition:opacity 500ms linear } #progress.done { opacity:0 } #progress span { positio

pace.js页面加载进度条插件_javascript技巧

本文简单介绍插件pace.js. 在页面中引入Pace.js,页面就会自动监测你的请求(包括Ajax请求),在事件循环滞后,会在页面记录加载的状态以及进度情况.此插件的兼容性很好,可以兼容IE8以上的所有主流插件,而且其强大之处在于,你还可以引入加载进度条的主题样式,你可以选择任意颜色和多种动画效果(例如简约.闪光灯,MAC OSX,左侧填充,顶部填充,计数器和弹跳等等动画效果),如果你擅长修改css动画,那你就可以做出无限种可能性的动画,为你的网站增添个性化特色! 调用方法: 引入Pace.j