首页 新闻 会员 周边

c++ linux环境下假设 xx.a 静态库里面包含一个类名为A,在c程序中也有一个A类,两个名字是一样的,然后编译链接xx.a静态库会发生什么?

0
悬赏园豆:200 [待解决问题]

c++ linux环境下假设 xx.a 静态库里面包含一个类名为A,在c程序中也有一个A类,两个名字是一样的,然后编译链接xx.a静态库会发生什么?

在一次偶然使用第三方静态库的时候 我习惯的加入了一个编码的.cpp里面 内部经常用,之后我在linux下编译 报错 函数重复定义, 是编码.cpp里面的一个函数

我下载了一个最新版本的编码.cpp(新版本函数一样但是里面的类名改了 ) 也就是把编码.cpp里面的类名改成和 第三方静态库里面引用的编码.cpp一致,编译成功!!

在后来我在想,如果是同类名会被覆盖导致不会报错重定义,那他会调用谁。 我测试是调用的我自己的编码.cpp,而不是静态库中的

这是为啥?真的和我分析的一样吗?会被覆盖?

HiXiaoYu的主页 HiXiaoYu | 初学一级 | 园豆:4
提问于:2023-03-24 10:42
< >
分享
所有回答(4)
1

在C++中,如果在程序中定义了与静态库中定义的类名相同的类,会发生名字冲突的情况。具体而言,链接器将无法区分程序中定义的类和静态库中定义的类,因为它们的名字相同。这将导致链接错误,因为链接器无法解决这种冲突。

对于你的第二个问题,如果你在编写的编码.cpp中定义了与第三方静态库中定义的类相同的类名和函数,编译器会将其视为一个新的定义,并将其用于编译链接。这意味着,如果你的编码.cpp中的函数与第三方静态库中的函数具有相同的签名(参数类型和返回类型),链接器将无法区分它们,因为它们具有相同的名字和签名。在这种情况下,可能会选择用程序中定义的函数覆盖静态库中定义的函数,这可能会导致未定义的行为。这个问题的解决方法是确保你的编码.cpp中的函数与第三方静态库中的函数具有不同的签名,以避免名字冲突和重定义错误。

Technologyforgood | 园豆:5575 (大侠五级) | 2023-03-27 21:48

也就是说完全一致的话是替换,而不一样只是函数名一致就会重复

支持(2) 反对(0) HiXiaoYu | 园豆:4 (初学一级) | 2023-03-28 13:00
0

这个刚好今天遇到了类似情况,动态库A.so里面有类X,动态库B.so里面有类X(同名,部分方法不同),在实际打算使用B.so中的类X(单例)时,通过单例方法访问X中的func时崩溃,dump定位在x的访问上,后面排查发现,instance方法创建的实际上是A.so中的类X,所以在访问x时会出现崩溃,因为A.so的类X没有x这个成员。
再往下查的方向其实就是看两个so代码汇编出来的静态ins变量的调用的构造函数地址,和so的加载机制,但这没必要,因为可能没有规范。
对于使用静态库链接,因为代码都在生成的可执行文件中,所以可以用汇编简单看一下具体使用的是A.so还是B.so的,可以使用nm和objdump命令。

class X {
public:
    static X& instance() {
       static X ins;
       return ins; 
   }
    void func(){ x = 1; };
    int x;
}
一位C++初学者 | 园豆:504 (小虾三级) | 2023-04-08 06:21
0

添加命名空间真的很重要

hehe1111 | 园豆:204 (菜鸟二级) | 2023-08-15 11:37
0

相同符号名称是编译不过报错的, 如果能编译过, 是不会发生覆盖的, 除非特别忽略了这个错误
可能是名称一样, 但是符号不一样
另外还有一个可能, 描述比较复杂, 比如库 x.a
在x.a 库中包含多个obj, 如
a.obj
b.obj
c.obj

在链接时加入x.a, 实际链接过程会对需要的函数从库中搜索, 最后发现需要 a.obj b.obj
如果在你的函数中有个函数 f1, 在c.obj 也有个函数 f1
虽然是一样的, 但是不会报错, 因为实际链接没有用到c.obj
但是如果在b.obj 有函数 f1, 就会报错

Yofoo | 园豆:394 (菜鸟二级) | 2024-02-15 00:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册