V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
redsonic
V2EX  ›  问与答

关于 windows 平台的静态编译

  •  
  •   redsonic · 2017-09-20 13:26:54 +08:00 · 1677 次点击
    这是一个创建于 2651 天前的主题,其中的信息可能已经有所发展或是发生改变。
    尝试用 /MT 参数编译了几个项目,编译成功了但目标机还是需要那几个 dll。估计是有些库函数不支持静态编译,但也没发现相关错误或警告(开了-Wall ) ,如果是 gnu 的编译器就会有警告。难道 windows 的都是去目标机上跑跑看或者拿 depends32 去检查?
    8 条回复    2017-09-21 17:18:14 +08:00
    ceflib
        1
    ceflib  
       2017-09-20 18:11:12 +08:00
    Microsoft Visual C++ 20xx Redistributable Package 你是没装这个?
    redsonic
        2
    redsonic  
    OP
       2017-09-20 21:25:33 +08:00
    @ceflib 指的是编译机还是目标机?其实和这个应该没关系吧,我要静态编译的是 https://github.com/ThinkPad-Forum/TPFanControl/tree/master/fancontrol 里面有个 TVicPort.lib ,我要把他静态编译到映像里。但实际即使用了 /MT 最后目标机还是要 TVicPort.dll 。
    ceflib
        3
    ceflib  
       2017-09-21 09:20:50 +08:00   ❤️ 1
    目前以 lib 后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。
    静态库是一个或者多个 obj 文件的打包,所以有人干脆把从 obj 文件生成 lib 的过程称为 Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个 obj 有错,即静态 lib 只是壳子。
    动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己 LoadLibary 调入 DLL 文件,然后再手工 GetProcAddress 获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。
    导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

    很明显你的这个 TVicPort.lib 只是个导入库,真正实现代码在 TVicPort.dll
    redsonic
        4
    redsonic  
    OP
       2017-09-21 11:04:58 +08:00
    @ceflib 了解, 我原以为和 linux 一样,ar 打包*.o 就肯定是静态库。 但还有个疑问 ,TVicPort.lib 是 33k,TVicPort.dll 是 28k。 如果说这个 TVicPort.lib 仅包含符号表等非实际代码未免不合情理,不过我也不清楚 windows 的编译器和运行时细节,如果有相关专著请介绍一些,中英文皆可。
    redsonic
        5
    redsonic  
    OP
       2017-09-21 11:26:38 +08:00
    @ceflib vs 里面的工具 lib /list TVICPORT.lib 显示全都是:

    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    TVicPort.dll
    ......

    意思这个 lib 就是 dll 套了点其他数据? 所以这大小就好解释了
    ceflib
        6
    ceflib  
       2017-09-21 12:53:21 +08:00
    可以参考这个 https://github.com/fancycode/MemoryModule,编译 exe 时把 dll 加载到资源里,运行时加载到内存里,获取 TVicPort.dll 的导出函数地址,TVicPort.dll 的导出函数调用方式都使用函数指针方式调用
    ceflib
        7
    ceflib  
       2017-09-21 13:00:44 +08:00
    可以看下 《程序员的自我修养》 《 Linkers and Loaders 》
    redsonic
        8
    redsonic  
    OP
       2017-09-21 17:18:14 +08:00
    Linkers and Loaders 虽然很好但太老了,而且微软的东西都是泛泛谈。不过那个 MemoryModule 是个好东西。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3110 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:22 · PVG 21:22 · LAX 05:22 · JFK 08:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.