【摘 要】很多进程可以同时使用一个DLL,在内存中共享该DLL的一个副本。相反,对于每个用静态链接库生成的应用程序,Windows 必须在内存中加载库代码的一个副本。
C# 语言从C和 C++语言演化而来,在语句、表达式和运算符方面使用了许多 C++ 功能。C# 语言在类型安全性、版本转换、事件和垃圾回收等方面进行了相当大的改进和创新。C# 语言提供对常用 API 样式(如 .NET 框架、COM、自动化和 C 样式 API 等)的访问。
C# 语言从C和 C++语言演化而来,在语句、表达式和运算符方面使用了许多 C++ 功能。C# 语言在类型安全性、版本转换、事件和垃圾回收等方面进行了相当大的改进和创新。C# 语言提供对常用 API 样式(如 .NET 框架、COM、自动化和 C 样式 API 等)的访问。
什么是动态链接库?DLL三个字母是Dynamic Link Library的缩写形式,动态链接库 (DLL) 是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个DLL中,该DLL包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL还有助于共享数据和资源,多个应用程序可同时访问内存中单个DLL副本的内容。
首先对接下来要做的事情做个简单的介绍,本文将利用C#语言创建一个名为MyDLL.DLL的动态链接库,在这个动态链接库文件中将提供两个功能一个是对两个参数交换他们的值,另一个功能是求两个参数的最大公约数。然后创建一个应用程序使用这个DLL,运行并输出结果。
创建以下三个C#代码文件:
MySwap.cs
using System;
namespace MyMethods
{
public class SwapClass
{
public static bool Swap(ref long i,ref long j)
{
i = i+j;
j = i-j;
i = i-j;
return true;
}
}
}
namespace MyMethods
{
public class SwapClass
{
public static bool Swap(ref long i,ref long j)
{
i = i+j;
j = i-j;
i = i-j;
return true;
}
}
}
MyMaxCD.cs
using System;
namespace MyMethods
{
public class MaxCDClass
{
public static long MaxCD(long i, long j)
{
long a,b,temp;
if(i>j)
{
a = i;
b = j;
}else
{
b = i;
a = j;
}
temp = a % b;
while(temp!=0)
{
a = b;
b = temp;
temp = a % b;
}
return b;
}
}
}
namespace MyMethods
{
public class MaxCDClass
{
public static long MaxCD(long i, long j)
{
long a,b,temp;
if(i>j)
{
a = i;
b = j;
}else
{
b = i;
a = j;
}
temp = a % b;
while(temp!=0)
{
a = b;
b = temp;
temp = a % b;
}
return b;
}
}
}
接下来的把这两个cs文件变成需要的DLL文件。
安装了Microsoft.NET Framework的操作系统上,在Windows所在目录下找到Microsoft.NET目录。这个目录下面提供了C#的编译器CSC.EXE,运行:
csc /target:library /out:MyDLL.DLL MySwap.cs MyMaxCD.cs
完成后可在本目录下面找到刚才生成的MyDLL.DLL文件。
/target:library 编译器选项通知编译器输出DLL文件而不是EXE文件。后跟文件名的 /out 编译器选项用于指定DLL文件名。
如果/out后面不跟文件名编译器使用第一个文件 (MySwap.cs) 作为DLL文件名。生成的文件为MySwap.DLL文件。
/target:library 编译器选项通知编译器输出DLL文件而不是EXE文件。后跟文件名的 /out 编译器选项用于指定DLL文件名。
如果/out后面不跟文件名编译器使用第一个文件 (MySwap.cs) 作为DLL文件名。生成的文件为MySwap.DLL文件。
简单写一个小程序来测试一下我们刚才写的两个方法是否正确:
MyClient.cs
using System;
using MyMethods;//这里引用定义的名称空间
class MyClient
{
public static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: MyClient <num1> <num2>");
return;
}
long num1 = long.Parse(args[0]);
long num2 = long.Parse(args[1]);
SwapClass.Swap(ref num1, ref num2);
//请注意,文件开头的using指令使得以在编译时使用未限定的类名来引用DLL方法
Console.WriteLine("The result of swap is num1 = {0} and num2 ={1}", num1, num2);
long maxcd = MaxCDClass.MaxCD(num1, num2);
Console.WriteLine("The MaxCD of {0} and {1} is {2}", num1, num2, maxcd);
}
}
using MyMethods;//这里引用定义的名称空间
class MyClient
{
public static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: MyClient <num1> <num2>");
return;
}
long num1 = long.Parse(args[0]);
long num2 = long.Parse(args[1]);
SwapClass.Swap(ref num1, ref num2);
//请注意,文件开头的using指令使得以在编译时使用未限定的类名来引用DLL方法
Console.WriteLine("The result of swap is num1 = {0} and num2 ={1}", num1, num2);
long maxcd = MaxCDClass.MaxCD(num1, num2);
Console.WriteLine("The MaxCD of {0} and {1} is {2}", num1, num2, maxcd);
}
}
若要生成可执行文件 MyClient.exe,请使用以下命令行:
csc /out:MyClient.exe /reference:MyLibrary.DLL MyClient.cs
/out 编译器选项通知编译器输出 EXE 文件并且指定输出文件名 (MyClient.exe)。/reference 编译器选项指定该程序所引用的DLL文件。
若要运行程序,请输入 EXE 文件的名称,文件名的后面跟两个数字,例如:
MyClient 123 456
输出结果为:
The result of swap is num1 = 456 and num2 = 123
The MaxCD of 456 and 123 is 3
The MaxCD of 456 and 123 is 3