【问题标题】:unresolved external symbol "_hypot" when using static library使用静态库时未解析的外部符号“_hypot”
【发布时间】:2011-10-12 03:55:10
【问题描述】:

我正在尝试重新编译链接 Ruby 库的旧游戏,但我不断收到此错误:

ruby18-mt-static-release.lib(math.obj):错误 LNK2001:未解决 外部符号_hypot

是否有任何解决方法不需要我找到该库的源代码并重新构建它?

我正在使用 Visual Studio 2010 和最新的 DirectX SDK。

【问题讨论】:

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


    【解决方案1】:

    我遇到了类似的问题。显然hypot曾经是一个可链接的函数,但现在(我有VS 2010)是一个调用_hypot的内联函数。在 math.h 中,这是完成此操作的唯一函数。我没有我正在使用的现有库的源代码,并且它已链接到它,因此它不能使用内联版本。如果我自己定义hypot,链接器会说它已经定义。以下工作可解决此问题:

    • 编辑 math.h 并注释掉内联版本的 hypot。
    • 将 hypot 实现为 extern "C" double hypot(double x, double y) {return _hypot(x, y);}
    • 重新链接

    丑,但是解决了问题。

    【讨论】:

      【解决方案2】:

      您正在使用库的 MT-STATIC 版本。您需要确保您的项目(代码生成->运行时库)也设置为多线程,而不是多线程 DLL。相反,您可以找到该库的 MT-DLL 版本。无论哪种方式,运行时库(MT 或 MTD)必须在您的程序和您要链接的所有库中保持一致。

      http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx

      【讨论】:

      • 而 ruby​​18-mt-static-release.lib 可能需要 MT-static 而不是 CRT 的 MT-DLL 版本。
      【解决方案3】:

      这是一个老问题,但我有一个新的解决方法,不需要修改 ma​​th.h

      我在 Visual Studio 2012 (VS2012) 中尝试将“msvcrt-ruby18-static.lib”静态链接到我自己的 dll 时遇到了类似的问题。我收到了这个错误:

      'unresolved external symbol __imp__hypot referenced in function _math_hypot'
      

      感谢 Matt 的回答,我们知道这是由 'ma​​th.h' 的变化引起的。

      这个函数:

      double hypot(double _X, double _Y)
      

      在vs2010之前是这样的关键字声明的dll导出函数:

      extern "C" __declspec(dllexport) double __cdecl hypot(...)
      

      从vs2010开始,变成了内联函数:

      static __inline double __CRTDECL hypot(...)
      

      幸运的是,在 VS2012 中,内联函数由宏 RC_INVOKED 包装。你可以试试这个公共域植入让它链接:

      #define RC_INVOKED
      #include <ruby.h>
      
      extern "C" __declspec(dllexport)
      double hypot(double x, double y)
      {
          if (x < 0) x = -x;
          if (y < 0) y = -y;
          if (x < y) {
              double tmp = x;
              x = y; y = tmp;
          }
          if (y == 0.0) return x;
          y /= x;
          return x * sqrt(1.0+y*y);
      }
      

      [注意] 我的项目是一个 DLL,我直接使用 dllexport 关键字。似乎无法直接定义 '__imp__' 前缀。我试图定义一个名为 __imp__hypot(...) 的函数,但失败了。

      【讨论】:

        【解决方案4】:

        自己实现hypot()。这很简单:

        double hypot(double x, double y) {
            double ax = fabs(x), ay = fabs(y);
            double xy = x/y, yx = y/x;
            return ax > ay
                ? ax * sqrt(1.0 + yx*yx)
                : ay * sqrt(1.0 + xy*xy);
        }
        

        【讨论】:

        • 错误 C2084:函数'double hypot(double,double)' 已经有一个主体
        • 尝试将其命名为 _hypot()
        • 您可能必须将其声明为 extern "C",因为它是 C99(不是 C++)函数。
        • 这不是hypot的正确实现,它对于非常大的数字会失败。
        • 没错,但有办法解决这个问题 (en.wikipedia.org/wiki/Hypot)。我试图帮助 OP 解决链接错误。
        猜你喜欢
        • 2020-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-27
        相关资源
        最近更新 更多