【转】C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件
这两天忙着把框架改为支持加载C++和Delphi的插件,来不及更新blog了。
原来的写的框架只支持c#插件,这个好做,直接用c#的反射功能便可。但是公司不是所有人都搞C#,也不是所有的程序C#都能很好的完成,又或者其他公司提供的API不是C#的,这个时候,就需要这个框架能够支持多种语言了。
废话不多说,进入正题。
上网一搜,C#加载非托管的dll,无非就是使用 DllImportAttribute 。然而,这个属性里面要指明dll所在的路径,因为又是写在属性中,因此是在编译的时候就已经把路径写死了,不能动态指定路径加载。
于是又找了下,终于发现了c#中的一个函数:Marshal.GetDelegateForFunctionPointer。这个函数的功能就是将非托管的函数指针转换为委托。至此,任务完成。Dll的功能无非提提供各种函数,组成所谓的API,有了上述的方法之后,在C#中定义相关的委托(方法的参数列表和参数类型要跟非托管的Dll的参数类型和参数列表对应,具体的对应请google),然后调用上述方法,将非托管的dll转换为相应的委托,这样就能调用非托管的dll了。
在C#中,我们定义相关的接口,在方法实现中调用相应的委托,这样,一个插件对象就完成了。下面给出相应的类库和使用实例。
1 public class LoadDll
2 {
3 #region Win32 API : Load dll
4 [DllImport("kernel32.dll")]
5 public static extern IntPtr LoadLibrary(string path);
6
7 [DllImport("kernel32.dll")]
8 public static extern IntPtr GetProcAddress(IntPtr lib, string funcName);
9
10 [DllImport("kernel32.dll")]
11 public static extern bool FreeLibrary(IntPtr lib);
12
13 [DllImport("kernel32.dll")]
14 public static extern IntPtr GetStdHandle(int nStdHandle);
15
16 [DllImport("user32", EntryPoint = "CallWindowProc")]
17 public static extern int CallWindowProc(IntPtr lpPreWndFunc, int hwnd, int msg, int wParam, int lParam);
18 #endregion
19
20 private IntPtr _dllLib;
21
22 /// <summary>
23 /// Initializes a new instance of the <see cref="LoadDll"/> class.
24 /// </summary>
25 public LoadDll()
26 {
27
28 }
29
30 /// <summary>
31 /// Initializes a new instance of the <see cref="LoadDll"/> class.
32 /// </summary>
33 /// <param name="path">The path.</param>
34 public LoadDll(string path)
35 {
36 _dllLib = LoadLibrary(path);
37 }
38
39 /// <summary>
40 /// 注销对象时释放资源
41 /// <see cref="LoadDll"/> is reclaimed by garbage collection.
42 /// </summary>
43 ~LoadDll()
44 {
45 FreeLibrary(_dllLib);
46 }
47
48 /// <summary>
49 /// 初始化dll的路径
50 /// </summary>
51 /// <param name="path">The path.</param>
52 public void InitPath(string path)
53 {
54 if (_dllLib == IntPtr.Zero)
55 _dllLib = LoadLibrary(path);
56 }
57
58 /// <summary>
59 /// 根据非托管的dll中的方法名称映射成托管的委托类型
60 /// </summary>
61 /// <param name="methodName">非托管的dll中的方法名称</param>
62 /// <param name="methodType">托管的委托类型</param>
63 /// <returns></returns>
64 public Delegate InvokeMethod(string methodName, Type methodType)
65 {
66 //获取非托管的dll中方法的地址
67 var methodPtr = GetProcAddress(_dllLib, methodName);
68 //将非托管的方法转换为委托
69 return Marshal.GetDelegateForFunctionPointer(methodPtr, methodType);
70 }
71 }
调用:
1 loadDll = new LoadDll(path);
2 stop = (StopHandler)loadDll.InvokeMethod("stop", typeof(StopHandler));
3 start = (StartHandler)loadDll.InvokeMethod("start", typeof(StartHandler));
4 init = (InitHandler)loadDll.InvokeMethod("init", typeof(InitHandler));
5 query = (QueryHandler)loadDll.InvokeMethod("query", typeof(QueryHandler));
6 setDatabaseInfo = (SetDatabaseInfoHandler)loadDll.InvokeMethod("setDatabaseInfo", typeof(SetDatabaseInfoHandler));
7 setMonitorInfo = (SetMonitorInfoHandler)loadDll.InvokeMethod("setMonitorInfo", typeof(SetMonitorInfoHandler));
c++中的导出方法:
1 /// 插件导出方法
2 extern "C" __declspec(dllexport) void setDatabaseInfo(LPCTSTR dbServer, LPCTSTR dbUser, LPCTSTR dbPass, LPCTSTR dbName);
3 extern "C" __declspec(dllexport) void setMonitorInfo(LPCTSTR _agentBm, LPCTSTR _com);
4 extern "C" __declspec(dllexport) void init();
5 extern "C" __declspec(dllexport) void start();
6 extern "C" __declspec(dllexport) void stop();
7 extern "C" __declspec(dllexport) LPCTSTR query(LPCTSTR devname, LPCTSTR id);
C#中的委托
1 ///<summary>
2 /// 处理Stop事件
3 ///</summary>
4 publicdelegatevoid StopHandler();
5 ///<summary>
6 /// 处理Start事件
7 ///</summary>
8 publicdelegatevoid StartHandler();
9 ///<summary>
10 /// 处理Init事件
11 ///</summary>
12 publicdelegatevoid InitHandler();
13 ///<summary>
14 /// 处理Query事件
15 ///</summary>
16 publicdelegatestring QueryHandler(string devName, string id);
17 ///<summary>
18 /// 处理SetDataBaseInfo事件
19 ///</summary>
20 publicdelegatevoid SetDatabaseInfoHandler(string server,string user,string password,string dbName);
21 ///<summary>
22 /// 处理SetMonitorInfo事件
23 ///</summary>
24 publicdelegatevoid SetMonitorInfoHandler(string agentBm, string com);
接下来怎么搞,你们都懂的
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注马非码的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/marvin/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责
【转】C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件相关推荐
- mkl_def.dll文件加载失败
mkl_def.dll文件加载失败 下载 mkl_def.dll文件的下载地址如下:Fix mkl_def.dll related errors in Windows 7, 8 or 10 | DLL ...
- 逆战d3dx10_43.dll文件加载失败及dll文件缺失损坏修复解决方案
废话前言:本人对电脑底层了解不太深,因此在前些天因为idea出现一个显示"构建进程终止异常"的bug,尝试网上很多解决方案都没有成功,无奈之下只好重装系统.但重装系统后,逆战又显示 ...
- 成功解决将crx后缀文件加载到谷歌浏览器作为插件使用
成功解决将crx后缀文件加载到谷歌浏览器作为插件使用 目录 解决问题 解决思路 解决方法 1.下载crx文件
- 用 C 语言开发一门编程语言 — 字符串与文件加载
目录 文章目录 目录 前文列表 字符串 读取字符串 注释 文件加载函数 命令行参数 打印函数 报错函数 源代码 前文列表 <用 C 语言开发一门编程语言 - 交互式解析器> <用 C ...
- cad二次开发——自动运行dll,加载菜单(收集)
1.自动加载dll的方法(个人觉得下面第4个方法会更方便) cad加载dll_实现CAD插件启动自动加载的三种方法_weixin_39774556的博客-CSDN博客从网上或者别处淘来的CAD插件,效 ...
- 工控机的io开发_C#调用工控机dll文件,实现对IO的控制
本文旨在记录,C#通过调用外部DLL文件实现对Nuvo3120工控机IO口的控制. 前期,了解了C++中.c\.h\.lib文件的区别,以及用这些文件生成DLL的方法,后面通过厂家直接找到了WDT_D ...
- sql文件加载出错_四十二、SparkSQL通用数据源加载(load)和保存(save)
SparkSQL能用数据加载(load)和保存(save) 对于Spark SQL的DataFrame来说,无论是从什么数据源创建出来的DataFrame,都有一些共同的load和save操作.loa ...
- Cocos2d之Texture2D类详解之将文件加载成Texture2D对象
一.声明 笔者以cocos2d框架cocos2d-x-3.3rc0版本的源码做分析.本文为笔者原创,允许转载和分享,只要注明文章出处即可. 二.简介 Texture2D类简介 Texture2D类允许 ...
- WSAStartup()函数以及DLL的加载
本节讲解 Windows 下 DLL 的加载,学习 Linux Socket 的读者可以跳过. WinSock(Windows Socket)编程依赖于系统提供的动态链接库(DLL),有两个版本: 较 ...
最新文章
- yii2 模型中set_Day184:人脸识别中open-set与close-set
- Java中的显示锁 ReentrantLock 和 ReentrantReadWriteLock
- 刚刚,官宣100000个炫酷微信红包封面,速度撸!
- Python中maketrans和translate方法
- windows2008文件服务器端口,windows server 2008 文件服务器不定期出现大量CLOSE_WAIT状态的连接,必须重启服务器,客户端才能访问共享。...
- Maven搭建SpringMVC+Mybatis项目详解【转】
- 计算机中字长名词解释,《计算机科学概论》复习题(内含参考答案)
- 鸿蒙日程管理若离,2020华为HDC日程确定,鸿蒙、HMS以及EMUI 11成最关注点
- 【Kafka】Kafka认证与授权
- JMeter使用CSV Data参数化,中文参数传递过程出现乱码问题解决
- 懒加载、瀑布流和LightBox实现图片搜索效果
- MFC 配置OpenCV在Picture控件上绘图
- 【Oracle】体系结构
- python列表append()函数
- configure: error: readline library not found/libreadline.so: undefined reference to tputs
- python编写的bt爬虫实践
- c语言求球的体积用const,牛客练习赛41 E.球的体积并(计算几何)
- 99美金和299美金的开发者证书的区别
- 希腊字母在Vim 中的输入方法
- 下载excel打开后弹出警告提示,文件类型和文件内容不符问题处理
热门文章
- 【C++深度剖析教程37】类模板的概念和意义
- SpringBoot 使用教程
- Intellij IDEA创建的Web项目配置Tomcat并启动Maven项目
- 小程序返回上一页并传参
- 潭州课堂25班:Ph201805201 爬虫基础 第九课 图像处理- PIL (课堂笔记)
- [原创]前端工作了一段时间经验总结,献给做前端的同学
- Memory及其controller芯片整体测试方案(上篇)
- 【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器
- (ZT)在日本市场推广 iPhone 应用的经验
- 解决用户控件循环引用的笨办法