C ++静态链接奇怪的行为

时间:2013-07-23 13:53:30

标签: c++ c visual-studio-2010

我正在开展一个大型项目,事实上,在两个地方,有些函数采用相同的参数并具有相同的名称,尽管它们做了不同的事情。我被建议使用Facade方法并将所有内容放在静态库中。然而它使程序非常奇怪。尽管包装器是独立的静态库并且具有单独的名称空间,但函数并没有彼此分离。始终从A.lib中调用函数 - 也是由B :: BF()包装器调用。

可执行:

#include <iostream>    
#include "A/AWrapper.h"
#include "B/BWrapper.h"

int main()
{
    std::cout<<"A="<<A::AF(2)<<std::endl;
    std::cout<<"B="<<B::BF(2)<<std::endl;   //uses function int F(int x) from A lib

    getchar();
    return 0;
}

文件结构如下:

Dir A:

FA.h, FA.c  //function int F(int x) is defined - C language
AWrapper.h, AWrapper.cpp //a simple wrapper function AF of int F(int x); C++

Dir B:

FB.h, FB.c  //function int F(int x) is defined - C language
BWrapper.h, BWrapper.cpp //a simple wrapper function AF of int F(int x); C++

以上是简单的程序调用它们。详细文件列表:

图书馆--------------:

FA.h:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

int F(int x);

#endif // A_H_INCLUDED

FA.c:

#include "FA.h"

int F(int x)
{
   return x*x;
}

AWrapper.h:

#ifndef AWRAPPER_H_INCLUDED
#define AWRAPPER_H_INCLUDED

namespace A{
   int AF(int x);
}

#endif // AWRAPPER_H_INCLUDED

AWrapper.cpp

#include "AWrapper.h"

extern "C"{
#include "FA.h"
}

namespace A{   
    int AF(int x)
    {
       return F(x);
    }
}

B库--------------: FB.h:

#ifndef B_H_INCLUDED
#define B_H_INCLUDED

int F(int x);

#endif // B_H_INCLUDED

FB.c:

#include "FB.h"

#define n 5

int F(int x)
{
   return -x*x*n;
}

BWrapper.h:

#ifndef BWRAPPER_H_INCLUDED
#define BWRAPPER_H_INCLUDED

namespace B{

   int BF(int x);
}

#endif // BWRAPPER_H_INCLUDED

BWrapper.h:

#include "BWrapper.h"

extern "C"{
#include "FB.h"
}

namespace B{

   int BF(int x)
   {
      return F(x);
   }
}

1 个答案:

答案 0 :(得分:3)

不,你不能这样解决。如果你有一个不在命名空间或类[而不是内联]的“自由函数”,它将具有相同的名称(如果它具有相同的参数/返回类型,则在C ++中) - 所以无论你包裹多少稍后,链接器仍将链接到它找到的函数的第一个版本。

有两个明显的解决方案:

  1. 重命名(一个)函数,使它们不再具有相同的名称。
  2. 将基本功能包装到命名空间和/或类中,以便获得限定名称。
  3. 这些解决方案都涉及修改FA.c和/或FB.c.

    另一种方法是为每组函数使用共享库 - 这样FA.c和FB.c永远不会在同一个共享库中,并且将FA.o静态链接到一个共享库,并且FB.o到另一个共享库。但这意味着拥有共享库,我希望您在选择静态链接时首先选择不这样做。

    如果代码是可编译的(也就是说,它不使用newdeletethis或其他C ++关键字作为变量名称,并且不会过于疯狂在C ++中将指针从一种类型传递到另一种类型而不使用强制转换等,你也可以这样做:

    FA.cpp:

    namespace A
    {
        #include "FA.c"
    }
    

    FB.cpp:

    namespace B
    {
        #include "FB.c"
    }