当使用静态库时出现未解决的外部符号"_hypot"

5

我正在尝试重新编译链接Ruby库的旧游戏,但是一直出现以下错误:

ruby18-mt-static-release.lib(math.obj): error LNK2001: unresolved external symbol _hypot

有没有不需要我找到该库的源代码并重新构建的解决方法?

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

4个回答

5
我遇到了类似的问题。显然,hypot曾经是一个可链接的函数,但现在(我使用的是VS 2010)它是一个内联函数,调用_hypot。在math.h中,这是唯一一个这样做的函数。我没有我正在使用的现有库的源代码,因为它已经链接了hypot,所以它不能使用内联版本。如果我只是定义自己的hypot,链接器会说它已经被定义了。以下方法可以解决这个问题:
  • 编辑math.h并注释掉或ifdef掉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


而 ruby18-mt-static-release.lib 可能需要 CRT 的 MT-static 而不是 MT-DLL 版本。 - user566408

2

这是一个旧问题,但我有一个新的解决方法,不需要修改 math.h

当我尝试在Visual Studio 2012 (VS2012)中将 'msvcrt-ruby18-static.lib' 静态链接到我的DLL时,遇到了类似的问题。我收到了以下错误:

'unresolved external symbol __imp__hypot referenced in function _math_hypot'

感谢Matt的回答,我们知道这是由于'math.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(...)的函数,但失败了。


0

自己实现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)' 已经有一个主体。 - zaratustra
尝试将其命名为_hypot()。 - Ferruccio
由于它是一个 C99 函数(而不是 C++),您可能需要将其声明为 extern "C"。 - Ferruccio
4
这不是 hypot 的正确实现方式,它无法处理非常大的数字。 - e.tadeu
没错,但有办法解决这个问题(http://en.wikipedia.org/wiki/Hypot)。我试图帮助OP解决链接错误。 - Ferruccio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接