неразрешенный внешний символ "_hypot" при использовании статической библиотеки - PullRequest
5 голосов
/ 24 июля 2011

Я пытаюсь перекомпилировать мою старую игру, которая связывает библиотеку Ruby, но я получаю эту ошибку:

ruby18-mt-static-release.lib (math.obj): ошибка LNK2001: не устранена внешний символ _hypot

Есть ли обходной путь для этого, который не требует от меня нахождения исходного кода для этой библиотеки и ее перестройки?

Я использую Visual Studio 2010 и последнюю версию DirectX SDK.

Ответы [ 4 ]

5 голосов
/ 07 апреля 2012

У меня была похожая проблема.Очевидно, что hypot раньше был связываемой функцией, но теперь (у меня VS 2010) встроенная функция, которая вызывает _hypot.В math.h это единственная функция, где это делается.У меня нет источника для существующей библиотеки, которую я использую, и с ней связана гипотеза, поэтому она не может использовать встроенную версию.Если я сам определяю гипотезу, линкер говорит, что она уже определена.Чтобы исправить это, необходимо выполнить следующие действия:

  • Отредактируйте math.h и прокомментируйте или ifdef из встроенной версии гипотеты.
  • Реализуйте гипотезу как внешнюю "C" двойную гипотезу (double x,double y) {return _hypot (x, y);}
  • Relink

Ужасно, но это решило проблему.

2 голосов
/ 31 марта 2013

Это старый вопрос, но у меня есть новый обходной путь, который не нужно изменять math.h .

Я столкнулся с аналогичной проблемой при попытке статической ссылки ' msvcrt-ruby18-static.lib 'в мою собственную DLL в Visual Studio 2012 (VS2012).Я получил эту ошибку:

'unresolved external symbol __imp__hypot referenced in function _math_hypot'

Благодаря ответу Мэтта мы знаем, что это вызвано изменением ' 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 (...) , и мне не удалось.

2 голосов
/ 25 июля 2011

Вы используете версию библиотеки MT-STATIC. Вы должны убедиться, что ваш проект (Code Generation-> Runtime Library) также настроен на многопоточную, а не многопоточную DLL. И наоборот, вы можете найти версию библиотеки MT-DLL. В любом случае, библиотека времени выполнения (MT или MTD) должна быть согласованной во всей вашей программе и во всех библиотеках, которые вы хотите связать.

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

0 голосов
/ 25 июля 2011

Реализуйте 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);
}
...