手写一次静态编译全过程

11 篇文章 0 订阅
首先建一个静态链接库项目:lllibbb
  1. 将它的 项目属性      ->      配置属性      ->      常规      ->      配置类型  修改为:静态库(.lib) 
    这个一般都是在新建项目的时候直接选择的。
  2. 新建一个头文件:myFun.h
    #ifndef MYFUN
    #define MYFUN

    int max_in_3( const int a, const int b, const int c );

    #endif
  3. 再新建一个源文件:myFun.cpp
    #include "myFun.h"
    int max_in_3( const int a, const int b, const int c )
    {
    if ( a > b )
    {
    return a > c ? a : c;
    }
    else 
    {
    return b > c ? b : c;
    }
    }
  4. 编译这个静态链接库项目lllibbb,在它的debug目录下得到lllibbb.lib
再新建一个控制台程序:test
  1. 将  myFun.h  和  lllibbb.lib  二个文件copy到test项目的目录下面。
  2. 在test的项目中添加现有的头文件myFun.h。
  3. 在test.cpp中编写:
    #include "stdafx.h"
    #include "myFun.h"
    #include <iostream>

    #pragma comment(lib, "lllibbb.lib")          //这行也可以用在  项目属性->链接器->输入->附加依赖项 中添加 lllibbb.lib 来替代

    int main( int argc, char** argv )

    int i = 3, j = 33332, k = 323;
    std::cout << max_in_3( i, j, k ) << std::endl;
    return 0;
    }
  4. 编译运行。
注意点:
  1. 二个项目(lllibbb 和 test)的运行时库版本必须相同。这里指的版本是debug版本和非debug版本的区别。
    /MT 和 /MD 同属于非debug版本
    /MTd 和 /MDd 同属于debug版本
    否则的话会报很多的错误:(以下二种)
    error LNK2005 : 重定义错误
    warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
  2. 详解 : warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library      您试图与不兼容的库链接。
    注意 运行时库现在包含可防止混合不同类型的指令。如果试图在同一个程序中使用不同类型的运行时库或使用调试和非调试版本的运行时库,则将收到此警告。例如,如果编译一个文件以使用一种运行时库,而编译另一个文件以使用另一种运行时库(例如单线程运行时库对多线程运行时库),并试图链接它们,则将得到此警告。应将所有源文件编译为使用同一个运行时库。有关更多信息,请参见使用运行时库(/MD、/ML、/MT、/LD)编译器选项。
    同样的道理,自己的工程在Debug模式下应该使用/MTd 或 /MDd、      在Release模式下应该使用/MT 或 /MD。


静态链接库LIB和动态链接库DLL的区别

1.什么是静态连接库,什么是动态链接库
         静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,
lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。

静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接 库。静态链接库与静态链接库调用规则总体比较如下。
实践证明:这是完全可以的,静态库中什么都能包含,静态库可以想象成就是代码!所以它什么都能做!

对于静态链接库(比较简单):
首先,静态链接库的使用需要库的开发者提供生成库的.h头文件和.lib文件。

生成库的.h头文件中的声明格式如下:
extern "C" 函数返回类型 函数名(参数表);
在调用程序的.cpp源代码文件中如下:
#include "..\lib.h"
#pragma comment(lib,"..\\debug\\libTest.lib") 
//指定与静态库一起链接

第二,因为
静态链接库是将全部指令都包含入调用程序生成的EXE文件中。因此如果用的是静态链接库,那么也就不存在“导出某个函数提供给用户使用”的情况,要想用就得全要!要不就都别要!:)  

对于动态链接库:
动态链接库的使用需要库的开发者提供生成的.lib文件和.dll文件。或者只提供dll文件。
首先我们必须先注意到DLL内的函数分为两种: 
(1)DLL 导出函数,可供应用程序调用; 
(2)DLL 内部函数,只能在 DLL 程序使用,应用程序无法调用它们。
因此调用程序若想调用DLL中的某个函数就要以某种形式或方式指明它到底想调用哪一个函数。


总结评论:

      所以,在生成静态链接库时,不需要给函数加上导出属性。即 int max_in_3( const int a, const int b, const int c ); 即可,不像动态链接的时候,要加上extern "C" _declspec (dllexport)。 在静态链接库中,所有的函数都是公开的,因为静态链接库是将全部指令包含入调用程序生成的EXE中去的,相当于把源代码都给别人了,所有的函数当然无法隐藏。

      在使用静态链接库的时候,只要有函数的原型就可以使用,如上面可以不用 #include "myFun.h" 。而直接声明一个 int max_in_3( const int a, const int b, const int c ); 就可以了。复制 myFun.h 过去仅仅是为了方便。对于声明了很多类和函数的时候几乎只能复制。

      使用静态链接库后,因为静态链接库是将全部指令包含入调用程序生成的EXE中去的。所以最后生成的EXE文件中已经包含了所有的代码,因此EXE运行的时候完全不需要静态库 lllibbb.lib,单个EXE中够运行。动态链接时就完全不一样,动态链接的程序必须能找到引用的DLL文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值