静态库和动态库(Windows版)

4 Windows创建和使用静态库

笔者这里使用的是VS2015,当然也可以使用其他工具。

4.1生成静态库

1.首先打开VS,先新建一个项目,选择win32控制台应用程序,当然选择win32项目也可以。

2.接下来选择“下一步”进入应用程序设置,这里选择静态库并去掉预编译头,当然也可以在创建项目后去掉也是可以的。最后点击“完成”即可创建项目。

3.创建头文件(.h)以及源文件(.cpp)

StaticLib.h

#ifndef _STATIC_LIB_H_
#define _STATIC_LIB_H_
#include 
namespace StaticLib
{
    void print_hello(); //Test function
}
#endif

StaticLib.cpp

#include "StaticLib.h"
void StaticLib::print_hello()
{
    std::cout << "Hello world!" << std::endl;
}

4.生成解决方案,我这里选择的是release。

5.编译成功后就可以在工程目录下看到静态库。

4.2使用静态库

1.还是创建个普通的win32控制台程序。

在应用程序设置界面选择“控制台应用程序”,还是不勾选“预编译头”。

2.我们把上面创建lib时的头文件包含到新创建的控制台程序中,同时将lib文件复制到工程目录下。当然也可在编写测试程序时使用库所在的路径。

3.然后在测试源文件中输入以下代码:

#include "StaticLib.h"
#pragma comment(lib,"WindowStaticLib.lib")
int main()
{
    StaticLib::print_hello();

    system("pause");
    return 0;
}

#pragma comment(lib,“xxx.lib”)表示链接xxx.lib这个库。

4.最后生成并执行工程。

值得注意的是,生成应用程序的环境应与创建库的环境一样。

当然还有一种调用方式。

首先在测试工程目录下新建如下文件夹,将库和头文件分别拷贝到相应的文件夹中。

然后在配置下工程属性:

另外还需要属性页面中选择链接器->输入->附加依赖项中添加新生成的库。

同样也能得到正确结果。

另外,调用的代码更改如下:

#include "StaticLib.h"
int main()
{
    StaticLib::print_hello();

    system("pause");
    return 0;
}

当然啦,也可以不配置链接器中的库。还是保留一下语句:

#pragma comment(lib,"WindowStaticLib.lib")

以上两种方式本质都是一样的,只是通过不同的方式来配置罢了。

5 Windows创建和使用动态库

5.1生成动态库

1.首先创建一个动态库工程。

和静态库一样,取消去掉预编译头,这里选择DLL。

2.创建头文件(.h)以及源文件(.cpp)

DynamicLib.h

#ifndef _DYNAMIC_LIB_H_
#define _DYNAMIC_LIB_H_
#include 
#define DLL_EXPORTS
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
extern "C" {
namespace DynamicLib
{
DLL_API void print_hello();
}
}
#endif // _DYNAMIC_LIB_H_

DynamicLib.cpp

#include "DynamicLib.h"
DLL_API void DynamicLib::print_hello()
{
   std::cout << "Hello world!" << std::endl;
}

【注1】__declspec(dllexport)是导出符号,也就是定义需要导出函数的dll中给导出函数的函数声明前面加上导出符号,表示该方法可以导出给其他DLL或者exe使用。

【注2】C++的代码加extern "C",是为了保证编译时生成的函数名不变,这样动态调用dll时才能。

3.选择release生成解决方案,最后生成的库如下图所示:

好了,动态库就创建好了。

5.2使用动态库

1.还是创建个普通的win32控制台程序。

2.将前面创建的动态库的头文件(.h),dll文件复制到与测试项目中。

3.编写测试

有两种方法调用动态库,一种隐式链接,一种显示链接。

先说第一种隐式调用。隐式调用需要.h文件,.dll文件,.lib文件。

在源文件加入如下代码:

#include "DynamicLib.h"
#pragma comment(lib,"WindowDynamicLib.lib")
int main()
{
    DynamicLib::print_hello();
    system("pause");
    return 0;
}

然后编译运行。

接下来在看看显式调用。显式调用需要.dll文件,.lib文件。

#include 
#include 

typedef int(*dllfun)(void);//定义指向dll中函数的函数指针

int main()
{
    HINSTANCE hlib = LoadLibrary(L"WindowDynamicLib.dll");

    if (!hlib)
    {
        std::cout << "load dll error
";
        return -1;
    }
    dllfun fun = (dllfun)GetProcAddress(hlib, "print_hello");
    if (!fun)
    {
        std::cout << "load fun error
";
        return -1;
    }

    fun(); //print_hello()

    FreeLibrary(hlib);

    system("pause");

    return 0;
}

结果和隐式调用一致。

显式链接需要.dll, 需要事先知道导出函数的签名,不需要.lib和.h文件

使用显式加载的好处:

6静态库和动态库总结

静态库:编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

静态库的代码在编译时链接到应用程序中,因此编译时库文件必须存在并且需要通过“-L”参数传递给编译器,应用程序在开始执行时,库函数代码将随程序一 起调入进程内存段直到进程结束,其执行过程不需要原静态库存在。

动态库:动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。相当于静态库,不同的应用程序可以使用同一份动态库,因此可以节省内存。另外,而且动态库还可被其他语言调用,诸如Python。

总之,静态库和动态库的载入时刻不同,静态库是编译时用到的,动态库是运行时用到的。以Windows为例,如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。

Linux版本如下:

静态库和动态库(Linux版)

展开阅读全文

页面更新:2024-03-07

标签:静态   动态   应用程序   函数   代码   方式   函数库   链接   文件   程序

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top