我有一个静态库,该库具有一个类栏,该类栏在C LIB和程序中的标头文件中定义了相同的接口。EXE的bar略有不同。CPP源代码并创建具有不同值的对象。请参阅下面的代码。
静态库文件。(lib_project foo_lib(
lib_project foo_lib.h
class Foo
{
public:
int printBarA() const;
};
lib_project foo_lib.cpp
#include <iostream>
#include "Foo_lib.h"
#include "Bar.h"
int Foo::printBarA() const
{
Bar bar;
std::cout << "bar.getA() : " << bar.getA() << std::endl;
return 0;
}
lib_project bar.h
// Lib Bar definition
class Bar
{
public:
Bar();
int getA() const;
private:
int a;
};
lib_project bar.cpp
#include "Bar.h"
Bar::Bar() : a(99) {} // Different value here
int Bar::getA() const { return a; }
主程序EXE代码(shared_class(
bar.h
// exe Bar definition
class Bar
{
public:
Bar();
int getA() const;
private:
int a;
};
bar.cpp
#include "Bar.h"
Bar::Bar() : a(66) { } // Different value here
int Bar::getA() const { return a; }
main.cpp
#include "Lib_projectFoo_lib.h"
int main(int argc, char** argv)
{
Foo foo;
foo.printBarA();
return 0;
}
一旦编译了程序的输出如下。foo_lib方法foo :: printbara((创建了bar.exe bar.cpp中定义的bar对象,并使用a = 66;而不是在lib bar.cpp中定义的,其具有a = 99;
D:shared_class>Releaseshared_class.exe
bar.getA() : 66
编译为DLL修复在Windows上的DLL,但是由于Linux上的共享库仍然存在,因此我需要一个与平台独立的修复。
所以我的问题是:
- 为什么会发生这种情况?(我想对.obj文件被丢弃在链接时间。(
- 我可以选择停止此行为的选择,以便使用foo_lib.lib的bar.cpp,并将使用bar bar.geta((:99?
- 将所有库文件包装在命名空间中?还是重命名课?我有实际情况下有很多文件。是否有任何链接器或编译器选择比工作?
谢谢
分辨率:
我必须在名称空间中包装每个班级,以避免任何冲突。一切都按预期工作。
您通过在同一程序中具有两个略有不同定义的同一类(::Bar
(来违反一个定义规则(ODR(。您程序的行为是完全未定义的。
要解决这个问题,您通过更改实际名称或将其放在名称空间中来重命名Bar
的一个定义。
(至于技术细节,为什么会发生这种情况,这是由于链接者使用静态库来解决依赖项的方式。但是由于它是UB,因此您不能依靠它。(