【发布时间】: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
我正在尝试重新编译链接 Ruby 库的旧游戏,但我不断收到此错误:
ruby18-mt-static-release.lib(math.obj):错误 LNK2001:未解决 外部符号_hypot
是否有任何解决方法不需要我找到该库的源代码并重新构建它?
我正在使用 Visual Studio 2010 和最新的 DirectX SDK。
【问题讨论】:
标签: c++ visual-studio-2010 linker
我遇到了类似的问题。显然hypot曾经是一个可链接的函数,但现在(我有VS 2010)是一个调用_hypot的内联函数。在 math.h 中,这是完成此操作的唯一函数。我没有我正在使用的现有库的源代码,并且它已链接到它,因此它不能使用内联版本。如果我自己定义hypot,链接器会说它已经定义。以下工作可解决此问题:
丑,但是解决了问题。
【讨论】:
您正在使用库的 MT-STATIC 版本。您需要确保您的项目(代码生成->运行时库)也设置为多线程,而不是多线程 DLL。相反,您可以找到该库的 MT-DLL 版本。无论哪种方式,运行时库(MT 或 MTD)必须在您的程序和您要链接的所有库中保持一致。
http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx
【讨论】:
这是一个老问题,但我有一个新的解决方法,不需要修改 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(...) 的函数,但失败了。
【讨论】:
自己实现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);
}
【讨论】: