动态链接库DLL使用学习笔记

使用C#或其他语言时经常会引用到DLL,分享一些学习笔记。
DLL(Dynamic Linkable Library),提供一些可以拿来用的变量,函数或类。 静态与动态链接库都是共享代码的方式,如果采用静态链接库,则无论愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是如果使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”引用和卸载这个与EXE独立的DLL文件。

1、DLL的编制与具体的编程语言及编译器无关
只要遵守约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用,像JAVA,C#调用C++编写的DLL。
在windows下的system32文件夹中可以看到许多.dll windows的大多数API都包含在这些DLL。像MessageBox函数就包含在user32.dll这个动态链接库中.

2、静态库编译
在VS下创建一个win32控制台应用程序,选择静态库,添加C++类,添加代码,完成后右击文件属性页,选择常规-输出目录-….\lib,选择平台工具集xp(保证兼容性)-编译,此时在lib文件夹中会生成文件。
在新的想要引用静态库的程序中,添加以上添加好代码的头文件.h,-右键进入属性页-选择C/C++-附加包含目录-(输入静态库头文件的目录)-链接器-常规-附加库目录….\lib-链接器-输入-附加依赖项-添加刚生成的.lib。

除了以上方法设置路径使用静态库,还可以在主程序中,添加头文件

#pragma comment(lib,"xxx.lib")//xxx代表需要引用的静态库

这样做的话就要把设置路径中的文件删除,防止多重定义。

3、DLL动态链接库编译
在VS下创建一个win32控制台应用程序,选择DLL(可以勾选导出符号,简便),看见新生成的dll.cpp等,dllmain.cpp作为自己用的动态库,可以不用过多关注,如果是多个程序的入口,则需要关注进程线程函数处理。添加代码,完成后右击文件属性页,选择常规-输出目录-….\dll,右键解决方案-属性-项目依赖项-选择主程序依赖于DLL。
右键主程序属性-链接器-常规-附加库目录-…..
常规-输出目录-….\bin;平台工具集xp;dll属性页-链接器-高级-导入库把
$(OutDir)改为..\..\lib;

#pragma comment(lib,"xxx.lib")//xxx代表需要引用的静态库

使用.lib编译,程序不灵活,跨语言不方便,在函数前加extern “C”可以使函数不重载,告诉编译器是C语言,名字不会改动。这样的话把引用的头文件,库文件,引用函数都删掉。
加以下代码:
#include<windows.h>;
typedef int(*DLLFUN)(void);生成一个函数指针

并在主函数main中加

HMODULE hdll = LoadLibrary(L"xx.dll");
if(!hdll){return -1;}
DLLFUN fun = GetProcAddress(hdll,"fndll");
fun();
FreeLibrary(hdll);//释放动态链接库

这种方法比较灵活,在很多项目都有用到,使扩展代码变得非常容易。
另外,看你要引用的dll是托管的还是非托管的。如果是托管的dll直接添加引用就可以,如果是非托管的有一段成熟代码可以拿来用

private object DllInvoke(string strDllFileName, string strNameSpace, string strClassName, string strDllProcName, object[] objArrayParams)
         {
             try
             {
                 Assembly mAssembly = Assembly.LoadFrom(strDllFileName);
                 Type[] mTypes = mAssembly.GetTypes();
                 foreach (Type mType in mTypes)
                 {
                     if (mType.Namespace == strNameSpace && mType.Name == strClassName)
                     {
                         MethodInfo mMethod = mType.GetMethod(strDllProcName);
                         if (mMethod != null)
                         {
                             object mObject = Activator.CreateInstance(mType);
                             return mMethod.Invoke(mObject, objArrayParams);
                         }
                         else
                         {
                             //MessageBox.Show("Load Report Dll File Failed!");
                         }
                     }
                 }
             }
             catch (Exception mEx)
             {
                 MessageBox.Show(mEx.Message);
             }
             return null;
         }

strDllFileName,你引用的dll文件名
strNameSpace,名称空间,不用说了吧
strClassName,dll的类名
strDllProcName,接口过程名
objArrayParams,接口过程参数表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值