现在的位置: 首页 > 综合 > 正文

VC.Net中创建与使用静态链接库(lib)和动态链接库(dll),以及它们的区别

2013年10月20日 ⁄ 综合 ⁄ 共 3202字 ⁄ 字号 评论关闭

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核心编程第四部分(动态链接库).)

抱歉!评论已关闭.