一、什么叫动态链接库?
动态链接库(也称为dll,即为“Dynamic Link Library”的缩写),是Microsoft Windows最重要的组成要素之一,Windows系统文件夹中就存在很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。
动态链接库是不能直接执行的,也不能接收消息,他是一个独立的文件,DLL 文件通常包含函数、类、变量和其他资源,可以被程序动态加载并调用。
DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
通过使用 DLL,程序可以在运行时动态链接到需要的函数或资源,而不需要将所有功能都静态地包含在可执行文件中。这样可以减少程序的内存占用,提高系统的效率。此外,当需要更新某个功能时,只需替换 DLL 文件而不必修改整个程序。
二、使用DLL优点:
1.使用较少的资源
2.推广模块式体系结构
3.简化安装和部署
三、DLL调用
1.使用DllImport特性:
这是用于调用非托管 DLL 的一种方式。你需要声明一个静态 extern 方法,在方法上应用 DllImport
特性指定 DLL 文件的名称。这种方式适用于调用其他语言(例如C++)书写的dll。
首先,应该在C#语言源程序中声明外部方法,其基本形式是:
[DllImport("DLL文件")]
修饰符 extern 返回变量类型 方法名称(参数列表)
using System;using System.Runtime.InteropServices;class Program{ [DllImport("YourDllName.dll")] public static extern void YourFunctionName();}
注意:需要在程序声明中使用System.Runtime.InteropServices命名空间。
DllImport只能放置在方法声明上。
DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径)。
返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。
若要使用其它函数名,可以使用EntryPoint属性设置,如:
[DllImport("user32.dll", EntryPoint="MessageBoxA")]static extern int MsgBox(int hWnd, string msg, string caption, int type);
若要设置字符格式,可以使用CharSet = CharSet.Unicode如:
[DllImport("cbbofspecmedia.dll",CharSet = CharSet.Unicode)]public static extern int nGetSpecMediaInfoParseExp(byte[] filePath, ExportCbbCallback callback);
通常,c++ dll库字符编码方式都为utf-8,c#调用dll时,若遇到中文字符的接收与传递,会出现中文字符显示乱码与无法传递。
由于.NET平台多采用Unicode字符集,可能为gb2312,utf-16等;若此时对接收到的参数,做utf-8到Unicode的转换,仍不能得到正确结果;同样,对参数进行Unicode到utf-8的转换,也不能正确传递数据。
原因在于从dll获取到的char已经隐式转换成为了string,由于utf-8与Unicode汉字编码字节数的不一致,导致隐式转换出错,之后再进行转换便不能得到正确结果。
解决办法:
在C#中,将string,转为byte[] 传给dll,(因为string就是一个byte[])。
string path = @"D:\workingDocument\视频\video.mp4";Byte[] bytePath = Encoding.UTF8.GetBytes(path);int v = cbb.nGetSpecMediaInfoParseExp(bytePath, (a,b)=>{ int aa = a; string bb = b; });