DLL的两种链接方式

一。DLL的创建

// DLLTest.h  
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif
EXPORT  int fun(int a,int b);

//#ifdef DLLTest_EXPORTS      //导出方法二
//#define DLLTest_API __declspec(dllexport)
//#else
//#define DLLTest_API __declspec(dllexport)
//#endif
//extern "C" DLLTest_API int fun(int a,int b); //自己写的 extern "C" 不可少
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "DLLTest.h"
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
int fun(int a,int b) //自己写的函数
{
    int d = a*b;
    return d;
}
//DLLTest_API int fun(int a,int b) //自己写的函数
//{
//    int d = a*b*2;
//    return d;
//}

二。DLL的两种链接方式:隐式链接和显式链接

共有两种库:
一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。
一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。

关于lib和dll的区别如下:
(1)lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。
(2)如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体内容;如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。使用静态编译的lib文件,在运行程序时不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才行。
(3)动态链接的情况下,有两个文件:一个是LIB文件,一个是DLL文件。LIB包含被DLL导出的函数名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到DLL文件。在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中相应函数代码的地址,从而节省了内存资源。DLL和LIB文件必须随应用程序一起发行,否则应用程序会产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。

(1)隐式链接

第一种方法是:添加lib附加依赖项: 项目-》属性-》链接器-》输入-》附加依赖项 -》添加Lib.lib文件(或者在源代码中加入指令#pragma comment(lib, “Lib.lib”)),并将.dll文件置入工程所在目录,然后添加对应的.h头文件。 

// TestDLLX.cpp : 定义控制台应用程序的入口点。采用隐式链接DLL
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
#include "DLLTest.h"  //加入头文件
#pragma comment(lib,"../Debug/DLLTest.lib")
int _tmain(int argc, _TCHAR* argv[])
{
	printf("输入:");
	int b,c;
	scanf("%d %d",&b, &c);
    int d = fun(b,c);
    printf("the result is: %d \n",d);
	system("pause");
	return 0;
}
(2)显式链接 
需要函数指针和WIN32 API函数LoadLibrary、GetProcAddress装载,使用这种载入方法,不需要.lib文件和.h头文件,只需要.dll文件即可(将.dll文件置入工程目录中)。

// TestDLL.cpp : 定义控制台应用程序的入口点。 显式链接DLL
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
typedef int (*DLLFUN)(int,int); //声明函数原型

int _tmain(int argc, _TCHAR* argv[])
{
	HMODULE hModule = ::LoadLibrary("../Debug/DLLTest.dll");//加载DLL库
   if (hModule == NULL)
   {
          FreeLibrary(hModule);
    }
    DLLFUN newfun = (DLLFUN)::GetProcAddress(hModule,"fun");//取得fun函数的地址
   if (newfun == NULL)
   {
          FreeLibrary(hModule);
    }
	printf("输入:");
	int b,c;
	scanf("%d %d",&b, &c);
    int d = newfun(b,c);
    printf("the result is: %d \n",d);
    ::FreeLibrary(hModule);//释放指定多态链接库
    system("pause");
	return 0;
}

使用LoadLibrary显式链接,那么在函数的参数中可以指定DLL文件的完整路径;如果不指定路径,或者进行隐式链接,Windows将遵循下面的搜索顺序来定位DLL:
(1)包含EXE文件的目录
(2)工程目录
(3)Windows系统目录
(4)Windows目录
(5)列在Path环境变量中的一系列目录




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值