1. 区别:
在程序中,有的时候需要去调用一些外部的商业算法,往往这类算法都是收费的算法库,说白了就是不让你看到内部是如何实现的,只开放一些方法,然后你调用这个方法之后,传入参数就能得到结果。通常这种算法库,都会被封装成库,而作为一个调用者,我们应该如何去使用这些库文件呢? 以下针对这部分做介绍:
主要分两种调用方式:
- 针对托管代码 (针对.Net平台开发的,如:C#.Net、VB.Net)
需要添加引用,然后引入命名空间using的方式调用。
using System.Text;
using System.Threading.Tasks;
- 非托管代码 (基于Win32非.Net平台开发的,比如使用C或者C++写的dll)
//System.Runtime.InteropServices:提供了托管和非托管之间的相互调用功能
System.Runtime.InteropServices
[DllImport("C_Dll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a, int b);
2. 实战一:
实现C#调用C写的外部库-----非托管类库
- 在VS中使用C写一个dll用于测试,步骤入下:
文件 / 新建项目 / 其他语言 / Visual C++ / Win32项目 / 命名后确定
Win32应用向导下一步 / 选择Dll,选择空项目 / 确定 / 右击”解决方案“源文件 / 选择添加新建项 / 选择C++.cpp文件 / 重命名后确定。然后插入以下代码:
/*这里封装一个dll,包含一个Add()方法*/
extern "C" _declspec(dllexport)int Add(int a,int b)
{
int result = a + b;
return result;
}
-
点击生成之后,在Debug目录下会看到一个dll,这个就是我们等一下要用到的。
-
在VS中使用C#写一个调用程序调用这个库,由于这个库是不是基于.Net的,所以不能直接引用,我们需要动态链接。
//提供了托管和非托管之间的相互调用功能
using System.Runtime.InteropServices;
namespace C_ShapeInvole
{
class Program
{
static void Main(string[] args)
{
int result = C_DllInvoke.Add(10, 2);
Console.WriteLine(result);
}
}
///调用者类
public class C_DllInvoke
{
[DllImport("C_Dll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a, int b);
}
}
- 到此为止,我们还不能直接调用,因为DllImport(“C_Dll.dll”)中的地址是一个相对地址,所以我们需要将上面的dll复制到调用程序的Debug目前下,然后生成。
- 运行结果:
3. 实战二:
实现C#调用C#写的托管类型-----托管类库
- 在VS中使用C#写一个dll用于测试,步骤入下:
文件 / 新建项目 / Visual C# / 类库 / 命名后确定
然后插入以下代码:
public static int Add(int a, int b)
{
return a + b;
}
-
点击生成之后,在Debug目录下会看到一个dll,这个就是我们等一下要用到的。
-
在VS中使用C#写一个调用程序调用这个库,由于这个库是基于.Net的,所以可以直接在解决方案中引用这个dll(系统会自动复制到所在exe的Debug下)。
-
引入命名空间:
-
调用:在CShape下有一个TestClass类,TestClass包含一个静态方法Add()。
int result = TestClass.Add(5, 5);
Console.WriteLine(result);
- 运行结果: