VC.Net中创建与使用静态链接库(lib)和动态链接库(dll),以及它们的区别. 收藏
<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData("text"); if (text && text.length>300) { text = text + "/r/n/n本文来自CSDN博客,转载请标明出处:" + location.href; clipboardData.setData("text", text); } }, 100); } } </script> <script type="text/javascript">function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
VC.Net中创建与使用静态链接库(lib)和动态链接库(dll),以及它们的区别.
使用静态库需要h文件和.lib,在项目中使用静态库需要以下步骤:
1.在项目中包含相应的静态库头文件.
2.在项目中加入静态库,有两种方法:
方法一:项目设置中引用.lib,Project-Property-Configuration Properties-link-Input-Additional Dependencies中添加.lib.
方法二: 在代码使用 #progma comment(lib,"lib文件名");
3.使用静态库中的函数.
一个静态链接库的例子:
创建一个空项目或Dll项目命名为UseLib.
项目设置(VC2005.Net):
Project-Property-Configuration Properties - General - Project Defaults - Configuration Type 选择 Static Library(.lib)
- //代码示例
- //UseLib.h
- #pragma once
- #ifdef __cplusplus
- extern "C" {
- #endif
- int GetMin( int a, int b);
- #ifdef __cplusplus
- }
- #endif
- //UseLib.cpp
- #include "UseLib.h"
- int GetMin( int a, int b)
- {
- return (a < b) ? a : b;
- }
- //编译.
- //然后在创建一个控制台程序,用于测试静态库.
- //main.cpp
- #include "../UseLib /UseLib.h" //这是包含.h.请更改为你的.h路径.
- #pragma comment(lib, "../lib/UseLib.lib") //这是包含.lib.请更改为你的.lib路径.
- int main( int argc, char * argv[])
- {
- int a = 11, b = 12, c = 0;
- c = GetMin(a, b);
- return 0;
- }
动态链接库一般包括.lib(导出函数),.h,.dll,使用动态库有两种情况:
1加载时的隐式链接,同使用静态库相似,分为三步:包含.h和引用.lib,使用导出函数;这种方法是在程序运行开始就将dll库载入内存, 所以如果程序运行时找不到dll文件将导致程序启动失败.
2运行时的显式链接,直接使用LoadLibrary 加载所需的动态库,然后指定所需的导出函数. 这种方法不需要动态链接库的.h和.lib文件.
LoadLibrary函数映射DLL文件映像到进程地址空间, 失败返回NULL,通过GetLastError()可以获得相关错误.
GetProcAddress函数使用函数名字取得函数的地址。利用该函数地址,就可以访问动态连接库的函数了。返回NULL表示获取失败.通过GetLastError()可以获得相关错误.
FreeLibrary通过检查动态连接库的引用计数器,判断是否还有别的程序在使用这个动态连接库。如果没有,就从内存中移去该动态连接库;如果有,将动态连接库的使用计数器减1。LoadLibrary则将引用计数加1。
一个动态链接库的例子:
创建一个空项目或Dll项目命名为UseDll.
项目设置(VC2005.Net):
Project-Property-Configuration Properties - General - Project Defaults - Configuration Type 选择 Dynamic Library (.dll)
Project-Property-Configuration Properties - C/C++ - Preprocessor- Preprocessor Definitions 添加 _USRDLL
- //UseDll.h
- #ifdef _USRDLL
- #define DllAPI extern "C" __declspec(dllexport)
- #else
- #define DllAPI extern "C" __declspec(dllimport)
- #endif
- DllAPI int GetMin( int a, int b);
- //UseDll.cpp
- #include "UseDll.h"
- DllAPI int GetMin( int a, int b)
- {
- return (a < b) ? a : b;
- }
- //然后在创建一个控制台程序,用于测试动态链接库.
- //main.cpp
- #include "windows.h"
- #include <stdio.h>
- //1表示使用隐式链接.
- //0表示使用显式链接.
- #define StaticLink 0
- #if StaticLink
- #include "../UseDll /UseDll.h" //这是包含.h.请更改为你的.h路径.
- #pragma comment(lib,"../lib/UseDlld.lib") //这是包含.lib.请更改为你的.lib路径.
- #endif
- int main( int argc, char * argv[])
- {
- int a = 11, b = 12, c = 0;
- #if StaticLink
- c = GetMin(a,b);
- /*
- 使用隐式链接注意事项,需要把.dll放到系统能找到的地方.下面加载dll的搜索顺序:
- 1) 包含可执行映像文件的目录。
- 2) 进程的当前目录。
- 3) Windows系统目录。
- 4) Windows目录。
- 5) PATH环境变量中列出的各个目录。
- */
- #else
- typedef int (*LPFNDLLFUNC)( int , int );
- LPFNDLLFUNC lpfnDllFunc;
- HINSTANCE hInst = LoadLibrary( "../lib/UseDlld.dll" ); //请更改为你的.dll路径.
- if (hInst == NULL)
- {
- printf("err: %d" , GetLastError());
- return 1;
- }
- lpfnDllFunc = (LPFNDLLFUNC)GetProcAddress(hInst, "GetMin" );
- if (lpfnDllFunc == NULL)
- {
- printf("err: %d" , GetLastError());
- FreeLibrary(hInst);
- return 1;
- }
- //调用GetMin
- c = lpfnDllFunc(a, b);
- FreeLibrary(hInst);
- #endif
- printf("GetMin( %d, %d): %d" ,a, b, c);
- return 0;
- }
通过示例我们可以看出,静态链接库的使用方法和隐式链接十分相似,它们都用到了.lib文件.这里一下说明他们.lib文件的区别:
静态库.lib它包含了变量和函数的实现。作为动态链接库的.lib不包含任何函数和变量,它只是列出所有已输出的函数和变量的符号名.
动态链接库和静态链接库的区别:
静态链接库在编译期把所有的代码和数据都生成到执行程序,运行时就不再需要库了。
动态链接库在编译期只建立一个引用的接口,而真正的代码和数据存放在另外的可执行模块中,在运行时再装入.
隐式链接和显式链接的区别:
隐式链接:程序在启动时就加载DLL模块.直到程序结束时才卸载DLL模块.在此期间可以直接调用Dll的函数等.
显式链接:在调用LoadLibrary()时才加载DLL模块,要使用函数通过GetProcessAddress()来得函数址址.调用FreeLibrary()就可以释放DLL资源.
(程序示例使用VC2005.Net编译通过. 欲知更多相关DLL信息可以参看windows核心编程第四部分(动态链接库).)