简体   繁体   中英

unresolved external symbol “_hypot” when using static library

I'm trying to recompile my old game which links the Ruby library, but I keep getting this error:

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

Is there any workaround for this that doesn't require me finding the source code to this library and rebuilding it?

I'm using Visual Studio 2010 and the latest DirectX SDK.

I had a similar problem. Apparently hypot used to be a linkable function but is now (I have VS 2010) an inline function that calls _hypot. In math.h this is the only function where this is done. I don't have source for the existing library I am using and it has hypot linked to it so it can't use the inline version. If I just define hypot myself the linker says it is already defined. The following works to fix this:

  • Edit math.h and comment or ifdef out the inline version of hypot.
  • Implement hypot as extern "C" double hypot(double x, double y) {return _hypot(x, y);}
  • Relink

Ugly, but it solved the problem.

This is an old question but I have a new workaround that do not need to modify math.h .

I met a similar issue when I tried to static link ' msvcrt-ruby18-static.lib ' into my own dll in Visual Studio 2012 (VS2012). I got the this error:

'unresolved external symbol __imp__hypot referenced in function _math_hypot'

Thanks to Matt's answer, we know it is caused by the change of ' math.h '.

This function:

double hypot(double _X, double _Y)

before vs2010 it was a dll export function declared by keyword like this:

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

since vs2010, it became an inline function:

static __inline double __CRTDECL hypot(...)

Luckily in VS2012, the inline function is wrapped by a macro RC_INVOKED . You can try this public domain implantation to let it link:

#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);
}

[ NOTICE ] My project is a DLL and I use the dllexport keyword directly. It seems the ' __ imp __ ' prefix cannot be defined directly. I tried to define a function named __ imp __hypot(...) and I failed.

You are using the MT-STATIC version of the library. You need to make sure your project (Code Generation->Runtime Library) is also set to multithreaded, not multithreaded DLL. Conversely, you can find the MT-DLL version of the library. Either way, the runtime library (either MT or MTD) must be consistent across your program and all libraries you want to link.

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

Implement hypot() yourself. It's pretty straightforward:

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM