Wince Lib 和 DLL介绍及使用

一、LIB和DLL介绍
DLL:动态链接库(dynamic link library)
LIB:有两种情况:
1)一种是LIB仅包含索引信息(函数所在的DLL文件和文件中函数位置的信息)且无实现,代码由运行时加载在进程空间中的DLL提供
2)一种时LIB既包含索引也包含实现(函数代码本身),在编译链接时直接将代码加入程序当中

注:
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依赖的文件:
1).h头文件(包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中)
2).LIB静态库(该库应该既包含索引也包含实现)
2、使用动态Dll依赖的文件:
1).h头文件(包含dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中)
2).LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误。
如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载
3).dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有.exe文件和.dll文件,并不需要.lib文件和.h头文件。

三、使用说明
1、静态库LIB的使用
1)静态库LIB生成
创建工程-》win32 project-》选择 static Library

//test.h
void testPrintf(void);

//test.cpp
void testPrintf(void)
{
	printf("testStaticLib printf\r\n");
}

最后编译生成。

2)静态库LIB使用
2.1)引入头文件
#include "test.h"
2.2)引入库
通过代码引入:#pragma comment(lib, "testStaticLib.lib")
通过配置引入:


2.3)实际使用
testPrintf();

 

2、动态库DLL的使用
1)动态库DLL生成
创建工程-》win32 project-》选择  DLL

//DllLibTest.h

#ifdef DLLLIBTEST_EXPORTS
#define DLLLIBTEST_API __declspec(dllexport)
#else
#define DLLLIBTEST_API __declspec(dllimport)
#endif
#if 0
// This class is exported from the DllLibTest.dll
class DLLLIBTEST_API CDllLibTest {
public:
	CDllLibTest(void);
	// TODO: add your methods here.
	
};
extern DLLLIBTEST_API int nDllLibTest;
DLLLIBTEST_API int fnDllLibTest(void);
#endif
extern "C" DLLLIBTEST_API void testDllPrintf(void);

 

//DllLibTest.cpp
#include "stdafx.h"
#include "DllLibTest.h"
#if 0
// This is an example of an exported variable
DLLLIBTEST_API int nDllLibTest=0;

// This is an example of an exported function.
DLLLIBTEST_API int fnDllLibTest(void)
{
	return 42;
}

// This is the constructor of a class that has been exported.
// see DllLibTest.h for the class definition
CDllLibTest::CDllLibTest()
{
	return;
}

void CDllLibTest::testDllPrintf(void)
{
	printf("testDllPrintf\r\n");
	return;
}
#endif

DLLLIBTEST_API void testDllPrintf(void)
{
	printf("testDllPrintf\r\n");
	return;
}

 2)动态库接口导出有两种方式:
2.1)采用__declspec
extern "C" __declspec(dllexport) void testDllPrintf();
说明:
C++在编译时,会对函数名进行处理,也就是说Test函数也许会变成Test@1等形式.为了避免这个情况,我们需要采用extern "C"关键字,用来告诉编译器,这个函数采用C语言的编译方式,
一方面在Dll中Test会以原名出现,另一方面也让C程序能够调用C++编写的Dll库.而__declspec(dllexport)则是告诉编译器,我们这个函数要作为对外接口.
2.2)采用def文件

注:使用隐式链接的话可以不用extern ”C“

 注:使用隐式链接和显式链接都会执行到DllMain。

最后编译生成。
3)动态库DLL使用
3.1)静态加载
3.1.1)引入头文件
#include "DllLibTest.h"
3.1.2)引入库
通过代码引入:#pragma comment(lib, "DllLibTest.lib")
通过配置引入:通过properties->Linker->input->Additional Dependence中添加


3.1.3)实际使用
testDllPrintf();


3.2)动态加载

//main.cpp

#include <stdio.h>
#include "test.h"
//#include "DllLibTest.h"
#include <windows.h>
//#pragma comment(lib, "testStaticLib.lib")
//#pragma comment(lib, "DllLibTest.lib") 该静态加载也可以通过properties->Linker->input->Additional Dependence中添加

typedef void (*DLL_TEST)(void);

void main(void)
{
	printf("hello world\r\n");
	testPrintf();
	 
	HINSTANCE hInstDll = LoadLibrary(TEXT("DllLibTest.dll"));
    if(hInstDll == NULL)
    {
      FreeLibrary(hInstDll);
    }
	//获取Dll函数地址
    DLL_TEST DllPrintf = (DLL_TEST) GetProcAddress(hInstDll,"testDllPrintf"); 
	if (DllPrintf == NULL)
    {
      FreeLibrary(hInstDll);
    }

	//testDllPrintf();
	DllPrintf();
	getchar();
	FreeLibrary(hInstDll);
	return;
}

//DllLibTest.h

#ifdef DLLLIBTEST_EXPORTS
#define DLLLIBTEST_API __declspec(dllexport)
#else
#define DLLLIBTEST_API __declspec(dllimport)
#endif
#if 0
// This class is exported from the DllLibTest.dll
class DLLLIBTEST_API CDllLibTest {
public:
	CDllLibTest(void);
	// TODO: add your methods here.
	
};
extern DLLLIBTEST_API int nDllLibTest;
DLLLIBTEST_API int fnDllLibTest(void);
#endif
extern "C" DLLLIBTEST_API void testDllPrintf(void);

 如果没有extern "C"会出现以下问题:

Unhandled exception at 0x00000000 in testWin.exe: 0xC0000005: Access violation.

 需要在编译库的时候就加上extern “C”

注:使用动态加载的话只需要.DLL库就可以,即不需要.LIB库和.h文件

四、静态库Lib和DLL的区别
1、static lib在link之后可以直接运行使用,dynamic lib还需要相应的dll配合
2、static lib需要建立工程进行编译,dynamic lib是编译Dll自动生成的附加产物
3、static lib没有函数入口点,也就是说,并没有类似于WinMain或DllMain的函数,简单的说,只是函数的一个集合而已
4、static lib包含索引和实现,dynamic lib只包含索引

五、总结
1、static lib使用需要.h、在模块中或代码中加入.Lib和将.Lib拷入工程目录
2、DLL使用
2.1)隐式链接
.h头文件、.Lib和DLL库放到工程目录,在代码中引入.h头文件和Lib库说明
2.2)显式链接
采用WIN32 API函数LoadLibrary、GetProcAddress装载。不需要.h和.Lib,只需要.DLL文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值