动态连接库

动态连接库学习笔记

规则DLL(不能导出整个类,可以使用MFC中的类)的导出与导入(显式利用.def文件)

导出:

1:选择regular Dll using MFC Dll
2:(项目名).cpp后填加函数的定义.在头文件处添加函数的声明.
3:.def文件中的EXPORTS后填加函数名
比如://MyDll.cpp
Void DisplayAppName(){…}
//MyDll.h-----这一步是否必要?还没有验证.
Void DisplayAppName();
.def中的EXPORTS后添加DisplayAppName

导入:

1:向项目中加入MyDll.lib库文件(Project->Add to Project注意,事先要把该文件放到项目中)
2:拷贝MyDll.dll文件到项目中或者Windows/system
在使用的地方直接使用:LoadLibrary(“DisplayAppName”);DisplayAppName();----没有在使用前进行声明所以要用LoadLibrary()来显式导入.

特点:

导出部分和其他的没什么区别.导入部分容易忘记对.lib文件的处理.代码中使用函数也是很方便的.只用一个LoadLibrary(strFunName);就可以

规则DLL的导入导出(隐式---利用extern “C” _declspec(dllexport/dllimport))来声明函数----和其他的函数的声明原理是一样的.

导出:

1:(项目名).cpp文件后面添加函数的定义部分;函数名前面和函数体前面都要添加代码,:
Extern “C” _declspec(dllexport) double MyCube( int data){AFX_MANAGE_STATE(AfxGetStaticModuleState());  …}
声明后就可以和其他的函数一样填写函数体了.这样就搞定了.

导入:

1:当然是.lib.dll文件的位置问题;.lib文件的导入问题(弄不好都会出错)
2:在要使用该导出函数的适当地方添加代码:extern “C” _declspec(dllimport) double MyCube(int data);
3:直接使用就可以了.

特点:

和前面的使用.def文件导出规则Dll文件中的函数一样方便.

扩展DLL(可以导出整个类,但还没有找到导出的详细资料.这里只导出函数.而且是非成员函数,在类的外面定义的函数)的导出与导入(显式)

导出:

1:(项目名).cpp后填加函数的定义
2:(项目名).def文件后填加 函数名
比如://MyDll.cpp-----MyDll为项目名称
Int max(int a,int b){…}
//MyDll.def中在EXPORTS后添加 max

导入:

1:只需要把.dll文件放到Windows/system或者项目文件夹中
2:根据.dll文件中的函数申明(返回类型,参数)来使用typedef int(*pMax)(int a,int b);
pMax Max;
3:HINSTANCE MyDll=NULL;
4:MyDll=AfxLoadLibrary(“MyDll.dll”);
5:Max=(pMax)GetProcAddress(MyDll,”函数名”);
6:函数名();//后面可以直接使用了
7:使用完了后记得要用AfxFreeLibrary(MyDll);释放资源
比如:typedef int(*pMax)(int a,int b);pMax Max;
HINSTANCE MyDll=NULL;
MyDll=AfxLoadLibrary(“MyDll.dll”);
Max=(pMax)GetProcAddress(MyDll,”Max”);
Max(i ,j );//直接使用了
AfxFreeLibrary(MyDll);
 
又一个例子
导出部分:int MaxNum(int a,int b)
{
    return a>b?a:b;
}----.cpp文件中
EXPORTS
    ; Explicit exports can go here
    MaxNum---.def文件中
 
typedef int(*pMaxNum)(int a,int b);----合适的地方加入
下面的为调用.dll函数的地方代码:
    HINSTANCE MyDll=NULL;
    MyDll=AfxLoadLibrary("5_dll.dll");
    pMaxNum MaxNumber;
    MaxNumber=(pMaxNum)GetProcAddress(MyDll,"MaxNum");
    int i=MaxNumber(43,9);
    CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT1);
    char buffer[80];
    sprintf(buffer,"%d",i);
    pEdit->SetWindowText(buffer);
    AfxFreeLibrary(MyDll);

特点:

导出部分也很简单;但是导入部分异常麻烦.其中步骤25很容易出错.但也有好处,可以使系统效率提高.

扩展DLL(导出整个类,导入用的是隐式调用-----头文件进行声明.方便,弹性大很多)

导出:

1:在要导出的类的前面添加AFX_EXT_CLASS.:class AFX_EXT_CLASS CMyClass:public CObject;//当然首先你要创建一个有CObject派生的类CMyClass

2:删除语句” #include “/ add additional includes here”,删除整整一行.在建立的类的.cpp文件的开始部分.

导入:

1:当然要把.dll文件放到合适的地方.你要使用的类的头文件.h也要放到项目中(不是debug文件夹中,而是外面,和其他的.cpp.h一起).还有要把.lib文件以新文件的方式添加到当前项目中(Project->Add to Project->Files,然后选择就可以了).这三个文件有两个文件.h.lib是在同一个文件夹中的,.dll文件放到合适的地方就好了.

2:在你要使用该类的地方添加.h.一般放在相应的头文件处;若很多地方要用到,可以考虑放到stdafx.h.

3:正确的使用该类就可以了.象使用项目中的其他类一样就可以了.

比如:不好举例子.

特点

导入导出都非常的方便.不用象显式应用那样调用很多的函数.但是.lib文件的处理要特别的小心.这是很容易忘记的部分.

   1、隐式的调用

   这种调用方式需要把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,在使用DLL中的函数时,只须说明一下后就可以直接通过函数名调用DLL的输出函数,调用方法和程序内部其他的函数是一样的。隐式调用不需要调用Load Library()Free Library()。程序员在建立一个DLL文件时,链接程序会自动生成一个与之对应的LIB导入文件。该文件包含了每一个DLL导出函数的符号名和可选的标识号,但是并不含有实际的代码。LIB文件作为DLL的替代文件被编译到应用程序项目中。

   当程序员通过隐式调用方式编译生成应用程序时,应用程序中的调用函数与LIB文件中导出符号相匹配,这些符号或标识号被写入到生成的EXE文件中。LIB文件中也包含了对应的DLL文件名(但不是完全的路径名),链接程序也将其存储在EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows根据这些信息发现并加载DLL,然后通过符号名或标识号实现对DLL函数的动态链接。所有被应用程序调用的DLL文件都会在应用程序EXE文件加载时被加载在到内存中。

   2、显式调用

   这种调用方式是指在应用程序中用Load LibraryMFC提供的AfxLoadLibrary显式的将自己所做的动态连接库调进来,并指定DLL的路径作为参数。LoadLibary返回HINSTANCE参数,应用程序在调用GetProcAddress函数时使用这一参数。当完成对动态链接库的导入以后,再使用GetProcAddress()获取想要引入的函数,该函数将符号名或标识号转换为DLL内部的地址,之后就可以象使用本应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用Free LibraryMFC提供的AfxFreeLibrary释放动态连接库。

   使用显式调用方式可以让程序员来决定DLL文件何时加载或不加载,而操作系统在载入应用程序时不必要将所有该应用程序所引用的DLL都一起加载到内存中,只要在使用某个DLL时再将其载入,这样就可以减少应用程序在初始加载时所使用的时间和对内存的消耗。

 

Extern “C”---C编译方式,防止C++编译时编译器添加的修饰名.

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值