C++动态库创建及使用1

2 篇文章 0 订阅
1 篇文章 0 订阅

静态库:在链接步骤中,连接器将从库文件中取得所需的代码,复制到生成的可执行文件中,这种库成为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令都全部被直接包含在最终生成的EXE文件中了。

动态库:动态链接库是一个包含可由多个程序同时使用的代码和数据库,DLL不是可执行文件。动态连接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个DLL中,该DLL包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。


那么静态链接库和动态链接库中的lib有什么区别呢?

静态库中的lib:该LIB包含函数代码本身(即包括函数的索引,也包括实现),在编译时直接将代码加入程序当中

动态库中的lib:该LIB包含了函数所在DLL文件和文件中函数位置的信息(索引),函数实现代码由运行时加载在进程空间中的DLL提供


总之,lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接库的程序运行起来,只需要dll。


//以上转自他处

接下来演示几种DLL的编写和使用的情况

1、新建项目 mathdll(供其它程序使用的动态库程序),分别加入头文件mathdll.h和源文件mathdll.cpp

mathdll.h

#ifndef MATHDLL_H
#define MATHDLL_H

#ifdef WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif

extern DLL_EXPORT int mathAdd(int a, int b);
#endif
mathdll.cpp

#include "mathdll.h"

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

编译后会生成一个DLL文件和一个LIB文件分别是:mathdll.dll 和 mathdll.lib

接下来创建一个调用程序mathTest,包含源文件mathTest.cpp

mathTest.cpp

#include <iostream>
#include "mathdll.h"
using std::cout;

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

int main(int argc, char* argv[])
{
    cout << "the sum of 1 and 2 is "<<mathAdd(1, 2);
    getchar();
    return 0;
}
将DLL文件放在文件当前目录,就可以正确运行程序,运行结果为


2、假设将动态库项目中的.h文件移出项目,并将.cpp文件改成

#ifdef WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif

int DLL_EXPORT mathAdd(int a, int b)
{
    return(a + b);
}

这时,我们并没有这个库的头文件,这时我们就必须知道cpp文件中的函数,将调用程序改成如下面即可:

#include <iostream>
//#include "mathdll.h"
using std::cout;

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

extern int mathAdd(int a, int b);
int main(int argc, char* argv[])
{
    cout << "the sum of 1 and 2 is "<<mathAdd(1, 2);
    getchar();
    return 0;
}

这样程序还是能够成功编译并运行。

3、接下来,我们将动态库项目中的.cpp文件改成如下:

#ifdef WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif

extern "C" DLL_EXPORT int mathAdd(int a, int b)
{
    return(a + b);
}
重新编译后,更换调用程序的库文件。重新编译调用程序,会出现如下错误:

1>ClCompile:
1>  mathTest.cpp
1>mathTest.obj : error LNK2019: 无法解析的外部符号 "int __cdecl mathAdd(int,int)" (?mathAdd@@YAHHH@Z),该符号在函数 _main 中被引用
1>C:\Users\Administrator\Documents\Visual Studio 2010\Projects\mathTest\Debug\mathTest.exe : fatal error LNK1120: 1 个无法解析的外部命令
1>
1>生成失败。


为何会产生这种情况?原因是在第三方库中mathAdd这个函数是通过C的方式编写的,而调用它的确实C++程序。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.而在C中,只是简单的函数名字而已,不会加入其他的信息.也就是说:C++和C对产生的函数名字的处理是不一样的。所以只要对调用程序作如下修改就能解决这个问题:

#include <iostream>
//#include "mathdll.h"
using std::cout;

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

extern "C" int mathAdd(int a, int b);
int main(int argc, char* argv[])
{
    cout << "the sum of 1 and 2 is "<<mathAdd(1, 2);
    getchar();
    return 0;
}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值