c#创建、使用Dll动态链接库

来源:互联网 发布:网络的利与弊教案 编辑:程序博客网 时间:2024/05/17 13:10

最近因为项目需要,需要调用一个动态链接库,由于以前没有接触过,也不知道如何编写调用DLL,特此记录下学习笔记。


一、什么是DLL以及使用它的好处

1 DLL (DynamicLink Library )

DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个DLL 副本的内容。DLL 是一个包含可由多个程序同时使用的代码和数据的库。(来自百度)

2 DLL的好处

1)当程序越来越庞大时,DLL避免了EXE文件的过大。分成DLL之后,不用把全部功能都集中到EXE里,需要的时候才调入内存。
2)DLL模块化了生产程序。DLL是产品,EXE就是个集装箱。因此对DLL模块的更新只需要替换此DLL文件即可,不用更新整个程序。
3)编译EXE时,不用编译DLL的内容,加快了编译速度。
4)DLL可重用。当一个DLL模式设计好之后,可以被其它项目或程序所引用。
5)DLL可以起到保密的作用。也就是说DLL可以将实现功能的源代码隐藏起来,调用者只能使用而不能看到其内部代码。

上述可能说的有些难懂,下面是项目开发遇到的难题,其中就是选择DLL连接库,可以感性认识DLL的好处:

发生的背景

在开发新项目中使用了新的语言开发C#和新的技术方案WEB Service,但是在新项目中,一些旧的模块需要继续使用,一般是采用C或C++或Delphi编写的,如何利用旧模块对于开发人员来说,有三种可用方法供选择:

第一、将C或C++函数用C#彻底改写一遍,这样整个项目代码比较统一,维护也方便一些。但是尽管微软以及某些书籍说,C#和C++如何接近,但是改写起来还是很痛苦的事情,特别是C++里的指针和内存操作;

第二、将C或C++函数封装成COM,在C#中调用COM比较方便,只是在封装时需要处理C或C++类型和COM类型之间的转换,也有一些麻烦,另外COM还需要注册,注册次数多了又可能导致混乱;

第三、将C或C++函数封装成动态链接库,封装的过程简单,工作量不大。

因此我决定采用加载动态链接库的方法实现,于是产生了在C#中如何调用自定义的动态链接库问题,我在网上搜索相关主题,发现一篇调用系统API的文章,但是没有说明如何解决此问题,在MSDN上也没有相关详细说明。基于此,我决定自己从简单出发,逐步试验,看看能否达到自己的目标。

“动态链接”这几字指明了DLLs是如何工作的。对于常规的函数库,链接器从中拷贝它需要的所有库函数,并把确切的函数地址传送给调用这些函数的程序。而对于DLLs,函数储存在一个独立的动态链接库文件中。在创建Windows程序时,链接过程并不把DLLs文件链接到程序上。直到程序运行并调用一个DLLs中的函数时,该程序才要求这个函数的地址。此时Windows才在DLLs中寻找被调用函数,并把它的地址传送给调用程序。采用这种方法,DLLs达到了复用代码的极限。


二、在VS2010中如何创建和编写DLL

方法很简单,就是在程序的解决方案中添加一个项目,然后选择“类库”。注意,一定要在“解决方案”上添加项目才行,在项目中只能添加类文件了。类库项目一但添加,在程序编译的时候就会自动生成为DLL文件。

编写DLL这和编写类文件代码是一致的。你可以在多个CS类文件中编写,也可以全放在一起CS类文件中编写。当然推荐的方式是根据功能分类将类库分别写在不同的CS文件中。(虽然在不同文件中,但同属一个项目的类文件会被编译进一个DLL库文件中)


三、在VS2010中如何使用自己编写的DLL

方法也很简单,在你的程序中的解决方案管理器里,找到“引用”然后点右键添加,在弹出的对话框中选择“浏览”,然后选择你刚才创建并编译过的DLL文件。然后在程序文件中使用using 来引入你DLL中的命名空间。注:如果DLL项目就在你当前的程序解决方案中,那么你可以直接在添加“引用”中选择“项目”而不是“浏览”。这样就可以直接引用本解决方案中编写的DLL类库。


上述都是文字描述,有兴趣的需要尝试自己编写DLL并调用的同学可以参考

http://jingyan.baidu.com/article/6525d4b1091539ac7d2e9407.html,上面有最简单的例程,我牛刀小试了一下,正确完成!


四.c#调用Matlab生成的DLL

1、创建一个简单的.m文件

打开Matlab 2009a,新建一个.m文件,输入如下代码:

function result=twice(inputvar);
result=2*inputvar;

将代码保存为twice.m文件,如图所示。

image

2、使用Matlab DeployTool生成.Net组件

在Matlab 2009a的Command Window中输入deploytool并回车,如图所示。

image

就可以打开Matlab的DeployTool,如图所示。

image

在DeployTool窗体中,点击新建按钮,打开新建项目对话框,如图所示。

image

在左边的列表中选择MATLAB Builder NE,并在右边的列表中选择.NET Component,我们将这个工程命名为twice.prj,并点击OK,则进入项目设置界面,如图所示。

image

在Twice文件夹中添加我们刚才建好的.m文件,如图所示。

image

点击编译按钮或使用快捷键Ctrl+B则对该工程进行编译。编译完成后的主窗口如图所示。

image

3、创建一个测试用的Windows应用程序,将其命名为MatlabTest,如图所示。

image

4、添加对MWArray.dll的引用

MWArray.dll一般位于[Matlab安装位置]\R2009a\toolbox\dotnetbuilder\bin\win32\v2.0文件夹中,我们注意到Matlab 2009a对应的MWArray.dll是2.9.0.0版本的。在进行Matlab版本升级的时候,比较头疼的就是这个dll。

image

因为版本升级意味着之前生成的dll都需要重新生成。关于版本升级的问题,我将在后面的博文中详细介绍。

之所以添加MWArray.dll,是因为在这种混合编程方式下,我们经常要

using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;

5、添加对Matlab生成的twice.dll的引用。

6、添加窗体中相应的组件。

添加一个Label控件,并修改其Text属性为“计算结果”;

添加一个Label控件,用于显示计算结果;

添加一个Button控件,用于执行计算方法。

设计好后的Form1窗体如图所示。

image

7、编写相应的后台代码。

 

C#代码 复制代码 收藏代码
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.ComponentModel;   
  4. using System.Data;   
  5. using System.Drawing;   
  6. using System.Text;   
  7. using System.Windows.Forms;   
  8. using MathWorks.MATLAB.NET.Arrays;   
  9. using twice;   
  10.     
  11. namespace MatlabTest   
  12. {   
  13.     public partial class Form1 : Form   
  14.     {   
  15.         public Form1()   
  16.         {   
  17.             InitializeComponent();   
  18.         }   
  19.     
  20.         private void button1_Click(object sender, EventArgs e)   
  21.         {   
  22.             int i = 5;   
  23.             Twice c = new Twice();   
  24.             MWArray result = c.twice((MWArray)i);   
  25.             this.label2.Text = result.ToString();   
  26.         }   
  27.     }   
  28. }  
[c#] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Text;  
  7. using System.Windows.Forms;  
  8. using MathWorks.MATLAB.NET.Arrays;  
  9. using twice;  
  10.    
  11. namespace MatlabTest  
  12. {  
  13.     public partial class Form1 : Form  
  14.     {  
  15.         public Form1()  
  16.         {  
  17.             InitializeComponent();  
  18.         }  
  19.    
  20.         private void button1_Click(object sender, EventArgs e)  
  21.         {  
  22.             int i = 5;  
  23.             Twice c = new Twice();  
  24.             MWArray result = c.twice((MWArray)i);  
  25.             this.label2.Text = result.ToString();  
  26.         }  
  27.     }  
  28. }  

8、执行并查看结果

image

在代码中输入了一个变量i并为其赋值5,可以看到经过调用Matlab计算,顺利返回计算结果10。


五、创建和使用DLL

一个实例可以参考:http://blog.csdn.net/cpcpc/article/details/6134463

创建新的动态链接库 (DLL) 项目

  1. “文件”菜单中,选择“新建”,然后选择“项目…”

  2. “项目类型”窗格中,选择“Visual C++”下的“Win32”

  3. “模板”窗格中,选择“Win32 控制台应用程序”

  4. 为项目选择一个名称,如 MathFuncsDll,并将其键入“名称”字段。为解决方案选择一个名称,如 DynamicLibrary,并将其键入“解决方案名称”字段。

  5. 单击“确定”启动 Win32 应用程序向导。“Win32 应用程序向导”对话框的“概述”页中,单击“下一步”

  6. “Win32 应用程序向导”中的“应用程序设置”页中,选择“应用程序类型”下的“DLL”(如果可用),或者选择“控制台应用程序”(如果“DLL”不可用)。某���版本的 Visual Studio 不支持通过使用向导创建 DLL 项目。您可以稍后对此进行更改,以将项目编译为 DLL。

  7. “Win32 应用程序向导”“应用程序设置”页中,选择“附加选项”下的“空项目”

  8. 单击“完成”创建项目。

向动态链接库添加类

  1. 若要为新类创建头文件,请从“项目”菜单中选择“添加新项…”将显示“添加新项”对话框。“类别”窗格中,选择“Visual C++”下的“代码”“模板”窗格中选择“头文件(.h)”为头文件选择一个名称,如 MathFuncsDll.h,并单击“添加”将显示一个空白文件。

  2. 添加一个名为“MyMathFuncs”的简单类,以执行常见的算术运算,如加、减、乘和除。代码应与以下内容类似:

    #ifdef MathFuncsDll_EXPORTS #define MathFuncsDll_API __declspec(dllexport) #else #define MathFuncsDll_API __declspec(dllimport) #endif // Windows 头文件: #include <windows.h>       
  3.   // Returns a + b         extern "C" MathFuncsDll_API double Add(double a, double b);      
  4.    // Returns a - b         extern "C" MathFuncsDll_API double Subtract(double a, double b);    
  5.     // Returns a * b         extern "C" MathFuncsDll_API double Multiply(double a, double b);    
  6.      // Returns a / b      // Throws DivideByZeroException if b is 0         extern "C" MathFuncsDll_API double Divide(double a, double b);
  7. 请注意此代码方法声明中的 __declspec(dllexport) 修饰符。这些修饰符使 DLL 能够导出该方法以供其他应用程序使用。有关更多信息,请参见 dllexport, dllimport

  8. 若要为新类创建源文件,请从“项目”菜单中选择“添加新项…”将显示“添加新项”对话框。“类别”窗格中,选择“Visual C++”下的“代码”“模板”窗格中,选择“C++ 文件(.cpp)”为源文件选择一个名称,如 MathFuncsDll.cpp,并单击“添加”将显示一个空白文件。

  9. 在源文件中实现“MyMathFuncs”的功能。

代码链接:http://download.csdn.net/source/2980458


更多关于DLL的调用可以参考:

http://blog.csdn.net/zlei2013141/article/details/6963524

http://bbs.ednchina.com/BLOG_ARTICLE_186713.HTM

http://blog.csdn.net/nocky/article/details/7687603



 更多,请关注:http://blog.csdn.net/tiandijun/,欢迎交流!


0 0
原创粉丝点击