对于.NET,DLL分为托管DLL和非托管DLL,简单来说,托管即是运行在CLR上的程序(由符合CLS的语言创建),非托管则不是由CLR托管运行的程序。因为托管的代码最终都被被翻译成IL来执行,所以它们之间互相调用彼此类型的DLL是很简单的,好像就是在调用自己的程序集一样(唯一的不同可能是你只能看到DLL中的元数据,而不是可修改的实现代码)。
引用托管DLL
新建一个类库,项目名为:MathFunctions,新建一个类,命名为:Circle,命名空间修改为Shape,代码如下:
using System;
namespace Shape
{
/// <summary>
/// 圆形计算
/// </summary>
public class Circle
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="radius">半径</param>
public Circle(double radius)
{
this.Radius = radius;
}
/// <summary>
/// 单位
/// </summary>
public string Unit { set; get; }
/// <summary>
/// 半径
/// </summary>
public double Radius { set; get; }
/// <summary>
/// 返回圆的面积
/// </summary>
/// <returns></returns>
public double Area()
{
return Math.PI * Radius * Radius;
}
/// <summary>
/// 周长
/// </summary>
/// <returns></returns>
public double Perimeter()
{
return Math.PI * Radius * 2;
}
}
}
将此项目编译成MathFunctions.dll,关闭VS,下面这个Console项目来调用它:
创建一个新的Console项目,命名为:Console,在解决资源管理器中右击其引用->添加引用->程序集->扩展,从浏览中找到方才生成的MathFunction.dll,增加引用。
这样引用DLL中的方法就像引用本程序集中的方法一样,唯一的区别是你没有办法看到DLL中的实现,并且你没有办法修改它(如果你查看DLL中方法的定义会发现其是以程序集的样式呈现),如下图:
值的注意的是,DLL中只保存实现部分,注释(函数签名等)保存在同名的XML文件中。所以你经常会发现初次请求一个属性或函数的注释时,VS可能会提示你文档正在加载中,这时VS做的就是在寻找XML文档。所以你引用了DLL,但是没有复制同名的XML文件到项目的目录下,那么你的元数据只有实现,没有注释。
上面 是C#调用C#DLL,其实调用VB.NET的DLL基本一样。
非托管DLL
还记得在VB6.0或者C++中调用API函数吗?C#中调用非托管DLL与此相似(至少表面是这样的),你需要申明一个与源DLL中对象相似的“壳子”,通过壳子来调用。