在C LIB和程序中具有相同接口的类.EXE版本是



我有一个静态库,该库具有一个类栏,该类栏在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上的共享库仍然存在,因此我需要一个与平台独立的修复。

所以我的问题是:

  1. 为什么会发生这种情况?(我想对.obj文件被丢弃在链接时间。(
  2. 我可以选择停止此行为的选择,以便使用foo_lib.lib的bar.cpp,并将使用bar bar.geta((:99?
    • 将所有库文件包装在命名空间中?还是重命名课?我有实际情况下有很多文件。是否有任何链接器或编译器选择比工作?

谢谢

分辨率:

我必须在名称空间中包装每个班级,以避免任何冲突。一切都按预期工作。

您通过在同一程序中具有两个略有不同定义的同一类(::Bar(来违反一个定义规则(ODR(。您程序的行为是完全未定义的。

要解决这个问题,您通过更改实际名称或将其放在名称空间中来重命名Bar的一个定义。

(至于技术细节,为什么会发生这种情况,这是由于链接者使用静态库来解决依赖项的方式。但是由于它是UB,因此您不能依靠它。(

最新更新