V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
byaiu
V2EX  ›  C++

不同版本的 visual studio 编译出来的 dll,可以混用吗?

  •  
  •   byaiu · 2021-06-29 13:29:23 +08:00 · 4515 次点击
    这是一个创建于 1246 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ( c++)有个依赖库想更新一下,用新一点的 visual studio 编译,用一些新的 c++特性。给之前用旧 visual studio 编译出来的程序使用。

    23 条回复    2021-07-13 19:40:02 +08:00
    newmlp
        1
    newmlp  
       2021-06-29 13:33:40 +08:00
    c++不行,C 可以
    codehz
        2
    codehz  
       2021-06-29 13:41:43 +08:00
    用 c 接口可以,或者以前的 com 接口
    用 c++的话,那得注意看版本号,一般来说 2015-2019 是兼容的(其他版本就互相不兼容了
    12101111
        3
    12101111  
       2021-06-29 13:41:46 +08:00
    17,19,22 通用的,其他更早的不行
    xdeng
        4
    xdeng  
       2021-06-29 13:59:11 +08:00
    可以混用 loadlibrary 加载,同 dll new malloc 出来的数据 用同 dll 的 delete free 即可。
    tabris17
        5
    tabris17  
       2021-06-29 14:42:39 +08:00
    你用__declspec(dllexport)导出函数,这个是 ABI 兼容的
    kssss
        6
    kssss  
       2021-06-29 16:02:19 +08:00
    dll 是通用的和版本没关系
    3dwelcome
        7
    3dwelcome  
       2021-06-29 16:34:23 +08:00
    @xdeng "同 dll new malloc 出来的数据 用同 dll 的 delete free 即可。"

    我记得 VC 编译器可以专门指定 Runtime 为 DLL,这样就可以跨 DLL 释放内存资源了吧。
    BrettD
        8
    BrettD  
       2021-06-29 19:04:32 +08:00 via iPhone
    我遇到的一个坑倒不是 Visual Studio,是链接了不同版本的 GCC 和 Clang 编译出来的动态库(两个不同的供应商提供的),会导致 C++抛出异常之后,程序的执行流随机乱飘
    ysc3839
        9
    ysc3839  
       2021-06-29 21:09:10 +08:00 via Android
    @tabris17 declspec dllexport 只是告诉链接器要导出这个符号,不会影响 ABI 。比如不同版本间 C++ ABI 不一致,加了这个那还是不一致。想要保证兼容,需要用 extern "C" 导出为 C 语言的符号。
    ysc3839
        10
    ysc3839  
       2021-06-29 21:10:17 +08:00 via Android
    @3dwelcome 可以使用 DLL 的 crt,但是不同编译器版本编译出来的程序使用的也可能是不同版本的 crt,此时仍然不能跨 DLL 释放内存。
    ysc3839
        11
    ysc3839  
       2021-06-29 21:16:29 +08:00 via Android
    @BrettD C++的异常一般都是内部使用,不会跨越 ABI 边界的。自己 throw 的异常自己 catch,然后正常返回,是不会出现问题的。同时建议给边界函数加上 noexcept,这样如果遇到没有 catch 的异常,会直接终止程序。
    jim9606
        12
    jim9606  
       2021-06-29 22:34:39 +08:00
    如果导出接口都是 C 接口通常没问题,C++接口你得确保链接相同大版本的 VC 库。VS2015+开始用的 VC Runtime 都是 14.x,确保运行时装的是较新版本的 VC 14 Redist 就行。
    BrettD
        13
    BrettD  
       2021-06-29 23:50:55 +08:00
    @ysc3839 几个链接的动态库都是第三方的闭源库,这就很蛋疼,提出要求让几个供应商都使用同样的工具链重新编译一次,等了三个星期
    ysc3839
        14
    ysc3839  
       2021-06-30 00:25:07 +08:00 via Android
    @BrettD 如果是 C++的接口确实没什么好办法,接口简单的话用 C 语言包装一层吧,复杂的话就没办法了。
    byaiu
        15
    byaiu  
    OP
       2021-06-30 08:21:11 +08:00 via iPhone
    能把 vsrubtime 静态连接到 dll 里吗?这样做有什么风险没有?
    @jim9606
    Mithril
        16
    Mithril  
       2021-06-30 09:19:14 +08:00
    Visual Studio 和 MSVC 不是一个东西。你可以在新版本的 Visual Studio 里面使用老版本的 Toolset,这样可以使用一些新的 Visual Studio 功能。
    同时即使是老版本的 MSVC 也可以支持不少新的 C++特性,看看你要用的那些特性在你之前那个版本的编译器里有没有,有的话 /std 选项打开就行了。
    tabris17
        17
    tabris17  
       2021-06-30 09:23:17 +08:00
    @ysc3839 哦,对的。长年不写 C,给忘记了。
    ysc3839
        18
    ysc3839  
       2021-06-30 11:25:53 +08:00
    @byaiu MSVC CRT 能静态链接。风险要具体分析了,如果多个 DLL 都是静态链接的话,不能互相释放内存指针,只能自己用自己的。一般来说为了节省空间,多 DLL 的程序会选择都动态链接。
    byaiu
        19
    byaiu  
    OP
       2021-06-30 18:01:48 +08:00
    @ysc3839 也就是说,如果 dll 内部能确保所有内存自产自销,静态链接 crt 应该就是可行的是吧
    ysc3839
        20
    ysc3839  
       2021-06-30 18:24:02 +08:00
    @byaiu 是的
    asuraa
        21
    asuraa  
       2021-07-01 10:06:05 +08:00
    微软的 com 技术了解下
    hyrious
        22
    hyrious  
       2021-07-12 13:51:37 +08:00   ❤️ 1
    #9 extern "C" 不如 def 好使 https://github.com/hyrious/rgss-railapi-achievements/blob/master/railapi/rail_wrapper.def

    以及真的需要 COM 吗(
    byaiu
        23
    byaiu  
    OP
       2021-07-13 19:40:02 +08:00 via iPhone
    追个后续:花了点时间把所有相关项目全部升级到 V142 了……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3753 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 00:52 · PVG 08:52 · LAX 16:52 · JFK 19:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.