一、什么是静态链接库,什么是动态链接库?

1、静态链接库就是你使用的.lib文件,库中的代码最后需要连接到你的可执行文件中去,所以静态连接的可执行文件一般比较大一些。在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*.LIB),Visual C++的编译器在链接过程中将从静态库中恢复这些函数和数据并把它们和应用程序中的其它模块组合在一起生成可执行文件。这个过程称为“静态链接”。

如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。

可以参考:http://www.cnblogs.com/Winston/archive/2008/07/05/1236273.html

1.1 windows下的静态链接库

1、通用:

      格式如下:#prama comment(lib,"XXX.lib")

  2、针对开发环境:

  •   如果使用Visual C++:可以在Project Setting-->Link中加入你的静态库,也可以直接把该.lib文件加入到你的工程中。
  •   如果使用Visual Studio,位置在 项目→配置属性→连接器→输入→附加依赖项 中加入.lib文件。

2、动态链接库英文为DLL,是Dynamic Link Library的缩写形式。所谓动态链接,就是把一些经常会共用的代码制作成DLL档,当可执行文件调用到DLL档内的函数时,windows操作系统才会把DLL档加载存储器内,DLL档本身的结构就是可执行文件,当程序需求函数才进行链接。通过动态链接方式,存储器浪费的情形将可大幅降低。

  动态链接库的加载方式分为两种:静态加载、动态加载。

2.1 静态加载

  1、需求:

    • 服务端的头文件
    • 服务端所产生的lib文件和dll文件

  2、客户端加载:

    • #prama comment(lib,"XXX.lib")

2.2 动态加载

    1、需求:

    • 服务端所产生的dll文件

  2、客户端加载:三步曲

    • LoadLibrary("DyLinkLib.dll")
    • GetProcAddress(hmod,"add");
    • FreeLibrary(hmod);

二、代码示例

1、静态链接库:

  • 服务端:工程名为StaticLibrary
StaticLib.h:

#ifndef ADD_H_
#define ADD_H_

int add(int a, int b);

#endif


StaticLib.cpp:

int add(int a, int b)
{
return a+b;
}

  产生:StaticLibrary.lib

  • 客户端:首先得将服务端的StaticLib.h头文件和StaticLibrary.lib文件发送给客户,这时客户端才能调用我们编写的静态链接库。
#include "StaticLib.h"
#include <iostream.h> #pragma comment(lib,"StaticLibrary.lib")
//这里的lib好像过滤器功能,告诉编译器要使用lib文件,其次通过"StaticLibrary.lib"名字查找
int main(void)
{
cout << add(,) << endl;
return ;
}

这里的静态链接库的链接采用windows平台静态链接的通用方式。

小结:静态链接库的编写和普通函数的编写一样,没什么特大的区别

2、动态链接库

  1. 静态加载方式
  • 服务端
DystaticLink.h

#ifdef MY_ADD
#define ADD_H extern "C" _declspec(dllexport)
#else
#define ADD_H extern "C" _declspec(dllimport)
#endif ADD_H int add(int a,int b);
DystaticLink.cpp

#define MY_ADD
#include "DystaticLink.h" int add(int a,int b)
{
return a+b;
}
  • 客户端
#include <iostream.h>
#include "DystaticLink.h" #pragma comment(lib,"DystaticLink.lib") int main()
{
cout << add(,);
return ;
}

小结:动态库的静态加载,需要服务端的"DystaticLink.h"头文件,以及服务端产生的DystaticLink.lib和DystaticLink.dll文件。

  2、动态加载

  动态加载可以参照:http://blog.sina.com.cn/s/blog_69e905cd0100m8zq.html

  • 服务端
DyLinkLib.h:

#ifdef ADD_H_
#define ADD_H extern "C" _declspec(dllexport)
#else
#define ADD_H extern "C" _declspec(dllimport)
#endif ADD_H int add(int a,int b);
DyLinkLib.cpp

#define ADD_H_
#include "DyLinkLib.h" int add(int a,int b)
{
return a+b;
}
  • 客户端
#include <iostream.h>
#include <windows.h> int main(void)
{
HMODULE hmod = LoadLibrary("DyLinkLib.dll");
if (!hmod)
{
cout << "加载失败" << endl;
return ;
}
typedef int (*AddProc)(int a, int b);
AddProc pAdd = (AddProc)GetProcAddress(hmod,"add");
if (!pAdd)
{
cout << "获取地址失败!" << endl;
return ;
}
cout << pAdd(,) << endl;
FreeLibrary(hmod);
return ;
}
  • 解析:首先看一下大致流程
  • LoadLibrary
    The LoadLibrary function maps the specified executable module into the address space of the calling process. For additional load options, use the LoadLibraryEx function. HMODULE LoadLibrary(
    LPCTSTR lpFileName // file name of module
    );

    1、LoadLibrary返回了模块句柄,这时,我们可以利用GetProcAddress函数得到动态库的某个函数地址。

    GetProcAddress
    The GetProcAddress function retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). FARPROC GetProcAddress(
    HMODULE hModule, // handle to DLL module
    LPCSTR lpProcName // function name
    );

    2、GetProcAddress函数返回一个函数指针,为了接收这个函数指针,我们的定义一个函数指针类型,这个函数指针类型要与要加载的动态库里的函数类型一致,此外还得将GetProcAddress返回值强制转换一下。

    typedef int (*AddProc)(int a, int b);
    AddProc pAdd = (AddProc)GetProcAddress(hmod,"add");

    3、得到了函数指针,我们就可以利用这个函数指针调用动态库的指定函数

    cout << pAdd(,) << endl;

    4、释放加载的动态库

    FreeLibrary(hmod);

小结:动态加载时,只需服务端发送DyLinkLib.dll文件即可。

C++ 静态、动态链接库的简单实现的更多相关文章

  1. C++高级编程2. 静态动态链接库

    C++高级编程2. 静态动态链接库20131018 1.动态链接库和静态链接库的区别: 静态链接库就是把lib文件中用到的函数代码直接连接进目标程序,程序运行的时候不在需要其他的库文件:动态链接库是把 ...

  2. 详谈 Java工厂 --- 静态工厂 【简单工厂模式】

    1.前言 什么是工厂模式? 就是为了尽可能将代码的耦合度降低而产生的设计模式. 这篇随笔讲解静态工厂的思路和具体操作. 2.总结 (1)静态工厂又称 简单 工厂模式 ,是最最简单的工厂模式. (2)优 ...

  3. mfc显示静态图片最简单的方法

    一致都是研究如何调用opencv显示动态图片,但是很多时候在显示图标的时候,都是需要显示静态图片,现在将最简单的方法总结下: 1.添加picture控件 2.添加资源,要求为bmp 3.修改属性 结果 ...

  4. jsp静态化之简单介绍

    package com.zwd.text; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputS ...

  5. linux gcc 静态 动态链接库

    静态链接库 首先生成依赖函数的目标文件 gcc -c source1.c source2.c; 然后归档目标文件到静态库 ar -rcs libYourID.a obj1.o obj2.o; 然后我们 ...

  6. rest-assured之静态导入及简单使用实例

    一.静态导入 为了有效的使用rest-assured,官网推荐从下列class中静态导入方法: io.restassured.RestAssured.* io.restassured.matcher. ...

  7. PHP 中的静态变量的简单使用

    静态变量的初始化只能在第一次static 声明的时候进行,这些静态变量只能在声明他的函数中访问到. 例如: <?php function do_something(){ static $firs ...

  8. C#中静态类、静态方法和静态变量的简单说明

    静态方法与静态变量一样,属于类本身,而不属于哪个类的一个对象.调用一个被定义为static的方法,只有通过在它前面加上这个类的名称.一般定义里说是可以通过实例调用的.其他语言我还没测试,但是在C#中是 ...

  9. nginx静态资源服务器简单配置

    有时候我们可以把服务器的一些文件放在固定目录以便下载,比如image,css,js等.就可以使用nginx转发静态资源. 参考链接:https://blog.csdn.net/name_is_wl/a ...

随机推荐

  1. Dot Net设计模式—MVC模式

    1 MVC设计模式简介 MVC结构是为那些需要为同样的数据提供多个视图的应用程序而设计的,它很好的实现了数据层与表示层的分离.MVC作为一种开发模型,通常用于分布式应用系统的设计和分析中,以及用于确定 ...

  2. Javascript and AJAX with Yii(在yii 中使用 javascript 和ajax)

    英文原文:http://www.yiiframework.com/wiki/394/javascript-and-ajax-with-yii /*** http://www.yiiframework. ...

  3. java.util.concurrent 包笔记 --- BlockingQueue

    BlockingQueue 队列接口,具有 4 组不同的方法用于插入.移除以及对队列中的元素进行检查.如果请求的操作不能得到立即执行的话,每个方法的表现也不同.这些方法如下:   Throws exc ...

  4. iOS中SQLite知识点总结1

    数据库(SQLite) 01-数据库简介 1.什么是数据库 数据库(Database)是按照数据结构来组织,存储和管理数据的仓库 2.数据库的分类 关系型数据库(主流) PC端:Oracle/MySQ ...

  5. Java_Web 连接池

    对于共享资源,有一个很著名的设计模式:资源池(Resource Pool).该模式正是为了解决资源的频繁分配﹑释放所造成的问题.为解决我们的问题,可以采用数据库连接池技术.数据库连接池的基本思想就是为 ...

  6. NSLayoutConstraint-代码实现自己主动布局的函数使用方法说明

    [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelat ...

  7. [ORACLE]数据库之间复制表

    ---------------------------------------------------------------------------- -------------ORACLE数据库管 ...

  8. How to trace a java-program

    up vote17down votefavorite 8 As a sysadmin I sometimes face situations, where a program behaves abno ...

  9. Linux 内核使用的 GNU C 扩展

    gcc核心扩展linuxforum(转)=========================== Linux 内核使用的 GNU C 扩展 =========================== GNC ...

  10. fork和exec函数

    #include<unistd.h> pid_t fork(void); 返回:在子进程中为0,在父进程中为子进程IO,若出错则为- fork最困难之处在于调用它一次,它却返回两次.它在调 ...