Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何链接(或绕过)两个定义相同符号的第三方静态库?_C++_C_Linker_Openssl_Static Libraries - Fatal编程技术网

C++ 如何链接(或绕过)两个定义相同符号的第三方静态库?

C++ 如何链接(或绕过)两个定义相同符号的第三方静态库?,c++,c,linker,openssl,static-libraries,C++,C,Linker,Openssl,Static Libraries,我不可能是唯一一个碰到这件事的人 我有一个C++应用程序,需要与SDK中的一个第三方和另一个静态库链接。出于某种令人沮丧的可怕原因,SDK将同一第三方库的子集重新编译到它们自己的(重命名的)库中,尽管符号本身的名称相同,并且没有封装在名称空间中。我的应用程序本身依赖于同一个第三方库 我已经考虑了一些选择,但也许我错过了一些东西,希望新的面貌能帮助我。也许我很接近,有人会知道下一步该怎么做。我将列举我迄今为止尝试过的方法以及每个解决方案的缺点: 与两者联系。 我收到大约2500行符号重新定义/大小

我不可能是唯一一个碰到这件事的人

我有一个C++应用程序,需要与SDK中的一个第三方和另一个静态库链接。出于某种令人沮丧的可怕原因,SDK将同一第三方库的子集重新编译到它们自己的(重命名的)库中,尽管符号本身的名称相同,并且没有封装在名称空间中。我的应用程序本身依赖于同一个第三方库

我已经考虑了一些选择,但也许我错过了一些东西,希望新的面貌能帮助我。也许我很接近,有人会知道下一步该怎么做。我将列举我迄今为止尝试过的方法以及每个解决方案的缺点:

  • 与两者联系。 我收到大约2500行符号重新定义/大小更改警告和错误。这是我第一次发现它们定义了相同的符号。我正在尝试用g++重新编译OpenSSL,并将其放到一个名称空间中…请参阅下面的编辑

  • 仅与SDK链接。 我得到了我自己的代码所依赖的未定义符号-这是当我发现他们对第三方库的重新编译是一个子集,或者至少配置了一个禁用的模块时

  • 仅与第三方库链接。 SDK报告了几个未定义的符号-其中一个实际上是第三方库中头文件中的#define,因此第三方库中的所有引用都解析为该定义,但外部的引用则不解析。我把它移到了c文件中,它解决了这个问题,但是我仍然有两个未解决的函数,我在任何地方都找不到。这是我迄今为止最接近的一次

  • 从一个库中剥离冲突符号,并在两个库中链接。 到目前为止,这还不起作用。SDK中静态链接的lib和我尝试使用的第三方lib版本之间可能存在版本问题,但看起来有些函数在符号之间移动了,因此通过删除符号,我无意中删除了其他地方需要的函数。SDK中符号中的函数与第三方库中符号中的函数之间似乎没有完美的映射。在不需要手动调整地址的情况下剥离功能是否合理

  • 我一直在研究libs中的符号:

    nm -C --defined-only lib<name>.a
    
    nm-C——仅定义lib.a
    
    以及使用以下方法提取整个对象:

    ar -x lib<name>.a <objname>.o
    
    ar-x lib.a.o
    
    希望这也能帮助那些不得不与相互冲突的第三方LIB建立联系的人。为了详细说明,第三方库是,SDK是-libcpopenssl.a是Opsec中的违规库


    **编辑-一个可能的后期解决方法可能是使用g++重新编译OpenSSL,并将整个内容放在一个名称空间中,然后链接两个LIB。我现在正在尝试…更多信息…

    谷歌搜索表明SSL\u get\u peer\u dh和dh\u dup实际上是libcpopenssl.A的新增内容,它们也不存在于我的OpenSSL副本中。所以你真的必须把这个库链接进去。在二进制级别将这两个库混合在一起(上面的方法4)不太可能奏效——OpenSSL对其ABI非常挑剔(它们通常都有.so文件版本控制在较小的数字),因此您必须非常幸运地拥有一个.so文件,它与它们的.a文件兼容

    我的建议是方法4的一个变体,但在源代码级别:您将在Opsec libcpopenssl.a中有链接,因为它是OpenSSL的修改版本,包含额外的符号(可能还有其他修改),并从OpenSSL源中获取所需的额外函数,并使用libcpopenssl.a重新编译这些对象,因此,他们可以使用Opsec版本中的函数。如果您只使用libcpopenssl.a未导出的几个OpenSSL函数,那么这是完全可行的

    诚然,这仍然是一种麻烦的方法,但这是一种保证符号兼容性的方法,当然前提是Opsec SDK没有对OpenSSL进行语义更改,这将破坏您在项目中使用的其他OpenSSL功能


    (我是StackOverflow的新手,所以我不知道这个建议是否是正确的答案,但无论如何,我没有发表评论的信誉点。如果不合适,我会删除它。)

    如果你好奇的话,在最新版本的OpenSSL中修改了249个文件,以使其能够编译。到目前为止,最常见的问题是大量的C风格指针类型转换,尤其是void*。现在我在梦中看到了“重新诠释演员”

    但这并不能单独解决这个问题——它仍然需要完整地放在名称空间中,这意味着再次修改所有文件以及我自己对它的内部引用。我想我现在要把这个传下去


    谢谢大家的帮助。

    您能省去opsec openssl衍生产品,转而链接您的openssl吗?听起来他们好像包括libcopopenssl.a,以防您没有OpenSSL链接。如果这些符号正确地拆分了它们的OpenSSL派生,那么它们应该连接起来。也就是说,链接库集中除该库之外的所有其他库,并将OpenSSL链接到中。这就是我在上面第3章中尝试的。我不得不将一个#define移到一个C文件中并重新编译,然后我仍然有两个未定义的符号。我在任何地方都找不到SSL\u get\u peer\u dh或dh\u dup。你不能用
    nm
    脚本从好的OpenSSL中获取符号吗。然后去掉这个名字列表中的坏库。如果它们具有静态链接,则内部引用已解析。如果没有,请使用
    -r
    -Ur
    链接器。我找不到关于这些函数的更多信息,谢谢!我对MODSIN OpenSSL感到厌倦了,但这正是我要去的地方,我将尝试编译C++并将其放入命名空间中。当我有更多信息时,我会更新。