未加星标

【win32】day11-windows的库/静态库/动态库

字体大小 | |
[系统(windows) 所属分类 系统(windows) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
windows 的库

由于项目的复杂程度,或者为了提高代码的

重用率等等,所以才引入了库程序。

库包含两种:

1 静态库:扩展名为 LIB 的文件,是不能被

加载的程序,可以理解为目标程序的

归档。

2 动态库:扩展名是 DLL 的文件,是可以被

应用程序加载的程序。

静态库

1 静态库的特点

1.1 目标程序的归档

1.2 静态库的代码会被嵌入到程序当中。

1.3 程序执行时不需要静态库存在

2 C语言静态库

2.1 创建静态库

创建Win32静态库项目,使用*.C文件建立项目。

int C_Add( int nAdd1, int nAdd2 ) { return ( nAdd1 + nAdd2 ); } int C_Sub( int nSub1, int nSub2 ) { return ( nSub1 - nSub2 ); }

2.2 添加静态库函数

2.3 在程序中将静态库导入

2.3.1 项目的Setting里设置, link选项

2.3.2 使用关键字 pragma

#pragma comment(lib, "../lib/winclib.lib")

2.4 使用静态库提供的函数

在C语言程序中,直接使用函数即可。

//导入静态库 #pragma comment(lib, "../lib/winclib.lib") int main( ) { int nAdd = 0; int nSub = 0; //使用C静态库的函数 nAdd = C_Add( 100, 100 ); nSub = C_Sub( 100, 100 ); printf( "ADD: %d\n", nAdd ); printf( "SUB: %d\n", nSub ); return 0; }

3 C++ 语言的静态库

3.1 创建静态库

创建 Win32 静态库项目 , 使用 *.CPP 文件建立项目。

int CPP_Add( int nAdd1, int nAdd2 ) { return ( nAdd1 + nAdd2 ); } int CPP_Sub( int nSub1, int nSub2 ) { return ( nSub1 - nSub2 ); }

3.2 添加静态库的函数

3.3 导入静态库

3.3.1 项目的 Setting 里设置

3.3.2 使用关键字 pragma

#pragma comment(lib, "../lib/wincpplib.lib")

3.4 定义库函数的原形

int CPP_Add( int nAdd1, int nAdd2 );

3.5 使用库函数

3.6 注意:

如果在 CPP 文件使用 C 语言静态库,定义的

静态库函数原形,需要增加 extern "C".

例如:

extern "C" int C_Add( int nAdd1, int nAdd2 );

// usecpplib.cpp : Defines the entry point for the console application. // #include "stdafx.h" //导入C++的静态库 #pragma comment( lib, "../lib/wincpplib.lib" ) #pragma comment( lib, "../lib/winclib.lib" ) //定义函数原形 int CPP_Add( int nAdd1, int nAdd2 ); int CPP_Sub( int nSub1, int nSub2 ); extern "C" { int C_Add( int nAdd1, int nAdd2 ); int C_Sub( int nSub1, int nSub2 ); } int main(int argc, char* argv[]) { //使用C++库函数 int nAdd = CPP_Add( 100, 100 ); int nSub = CPP_Sub( 100, 100 ); printf( "ADD: %d\n", nAdd ); printf( "SUB: %d\n", nSub ); //使用C库函数 int nAdd2 = C_Add( 100, 100 ); int nSub2 = C_Sub( 100, 100 ); printf( "C_ADD: %d\n", nAdd ); printf( "C_SUB: %d\n", nSub ); return 0; } 动态库

1 动态库的好处

1.1 可以提供模块化的方式,方便协调开发。

1.2 对源代码保护

1.3 减小可执行文件的大小

1.4 提供代码的重用率

2 动态库的基本使用方法

2.1 动态库的创建

2.2 加载动态库

2.3 获取并使用库函数、变量或类

2.4 释放动态库

3 动态库的函数

3.1 创建

3.1.1 创建DLL的项目

使用Win32 DLL项目,创建DLL,添加相应的文件。

3.1.2 增加动态库函数

3.1.3 导出动态库函数

3.1.3.1 使用__declspec(dllexport)方式

在函数前增加这个关键字,例如

__declspec(dllexport) int Dll_Add()

3.1.3.2 增加 extern "C" 方式,即

extern "C" __declspec(dllexport)

以C语言方式导出函数

#include "windows.h" #include "stdio.h" BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { printf( "DLL=%p, Reason=", hinstDLL ); switch( fdwReason ) { case DLL_PROCESS_ATTACH: printf( "DLL_PROCESS_ATTACH\n" ); break; case DLL_THREAD_ATTACH: printf( "DLL_THREAD_ATTACH\n" ); break; case DLL_THREAD_DETACH: printf( "DLL_THREAD_DETACH\n" ); break; case DLL_PROCESS_DETACH: printf( "DLL_PROCESS_DETACH\n" ); break; } return TRUE; } //C++导出方式 __declspec(dllexport) int Dll_Add( int nAdd1, int nAdd2 ) { return ( nAdd1 + nAdd2 ); } //C的导出方式 extern "C" __declspec(dllexport) int Dll_Sub( int nSub1, int nSub2 ) { return ( nSub1 - nSub2 ); } //DEF的导出方式 int Dll_Mul( int nMul1, int nMul2 ) { return ( nMul1 * nMul2 ); }

3.1.3.3 使用 DEF 文件导出

增加扩展名为 DEF 的文件到项目中 .

在 DEF 文件中添加导出定义 .

LIBRARY dllfunc.dll // 导出库

EXPORTS // 导出表

Dll_Mul @1 // 导出函数

Dll_Div @2

LIBRARY dllfunc.dll EXPORTS Dll_Mul @1

3.2 使用

3.2.1 隐式链接

3.2.1.1 导入 LIB

项目的 Setting 或者使用 #pragma 导入 , 例如 :

#pragma comment( lib, "../lib/dllfunc.lib")

3.2.1.2 定义函数原形

声明一个和导出函数一致的函数定义 .

如果 DLL 采用 extern "C" 导出函数 ,

需要定义 extern "C" 方式函数原形

3.2.1.3 使用函数

直接函数即可

3.2.1.4 应用程序查找 DLL 的路径

1) 查找当前应用程序的目录 .

2) 当前的工作目录

3) 查找 Windows System32 的目录

4) 查找 Windows System 的目录

5) 查找 Windows 目录

6) 查找环境变量 PATH 指定路径

// CallDllFunc.cpp : Defines the entry point for the console application. // #include "stdafx.h" //导入DLL的Lib文件 #pragma comment( lib, "../lib/dllfunc.lib") //定义函数原形 int Dll_Add( int nAdd1, int nAdd2 ); extern "C" int Dll_Sub( int nSub1, int nSub2 ); int Dll_Mul( int nMul1, int nMul2 ); int main(int argc, char* argv[]) { // 使用函数 int nAdd = Dll_Add( 100, 100 ); int nSub = Dll_Sub( 100, 100 ); int nMul = Dll_Mul( 100, 100 ); printf("Dll_Add: %d\n", nAdd ); printf("Dll_Sub: %d\n", nSub ); printf("Dll_Mul: %d\n", nMul ); return 0; }

3.2.2 显示链接

3.2.2.1 加载动态库

HINSTANCE LoadLibrary(

LPCTSTR lpLibFileName );//DLL 的路径

返回加载好 DLL 的句柄

3.2.2.2 定义函数原形对应的函数指针

3.2.2.3 获取函数地址

FARPROC GetProcAddress(

HMODULE hModule,//DLL 的句柄

LPCSTR lpProcName );// 函数的名称

返回对应函数地址

注意 :

1 对于 __declspec(dllexport) 导出的函数 ,

由于函数名称发生变化 , 所以无法使用

函数名称获取对应的函数地址 , 所以

尽量采用隐式链接的方式 .

2 extern "C" 或 DEF 方式导出的函数 ,

可以正常的使用函数名称获取函数地址 .

3.2.2.4 使用函数

3.2.2.5 释放动态库

FreeLibrary

// InvokeDllFunc.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "windows.h" typedef int ( * DLL_ADD )( int nAdd1, int nAdd2 ); typedef int ( * DLL_SUB )( int nSub1, int nSub2 ); typedef int ( * DLL_MUL )( int nMul1, int nMul2 ); void UseDll( ) { //加载动态库 HMODULE hDll = (HMODULE) LoadLibrary( "dllfunc.dll" ); if( hDll == NULL ) { printf( "Load Failed\n"); return; } printf( "DLL Handle: %p\n", hDll ); //定义函数指针 DLL_ADD Dll_Add = NULL; DLL_SUB Dll_Sub = NULL; DLL_MUL Dll_Mul = NULL; //获取函数地址 Dll_Add = ( DLL_ADD ) GetProcAddress( hDll, "Dll_Add" ); if( NULL == Dll_Add ) { printf( "Get Dll_Add Failed\n"); } printf( "Dll_Add: %p\n", Dll_Add ); Dll_Sub = ( DLL_SUB ) GetProcAddress( hDll, "Dll_Sub" ); if( NULL == Dll_Sub ) { printf( "Get Dll_Sub Failed\n

本文系统(windows)相关术语:三级网络技术 计算机三级网络技术 网络技术基础 计算机网络技术

主题: C++WindowsC语言SUUBDURY变量模块化
分页:12
转载请注明
本文标题:【win32】day11-windows的库/静态库/动态库
本站链接:http://www.codesec.net/view/480399.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(windows) | 评论(0) | 阅读(43)