g ++ — Поиск подходящих библиотек Windows для связи, чтобы скомпилировать библиотеку FANN

По разным причинам я пытался собрать FANN Библиотека сама. Я на Windows 10 с MinGW. Для простоты я собирался начать что-то вроде этого:

g++ mushroom.c -o shroom.exe -lm -I src\ -I src\include\ src\doublefann.c

(mushroom.c включает в себя <stdio.h> а также "fann.h".)

С использованием -I src\ -I src\include\ src\doublefann.c позволил мне избавиться от различных неопределенных ошибок ссылок, возникающих из-за того, что заголовочные файлы не были найдены, но теперь он продолжает выдавать следующую неопределенную ссылку:

doublefann.c:(.text+0x4ee9): undefined reference to GetTickCount()

К вашему сведению, это появляется в fann.h (строка 54):

/* COMPAT_TIME REPLACEMENT */
#ifndef _WIN32
#include <sys/time.h>
#else   /* _WIN32 */
#if !defined(_MSC_EXTENSIONS) && !defined(_INC_WINDOWS)
extern unsigned long __stdcall GetTickCount(void);

Короче говоря, это похоже на ошибку при связывании библиотек Windows, и я не знаю, как действовать, чтобы найти соответствующие ссылки.

Вот полный fann.h и полный doublefann.c

0

Решение

РЕДАКТИРОВАТЬ: После того, как я пошел спать прошлой ночью, я усовершенствовал свой подход, чтобы вам не приходилось редактировать фактические исходные файлы FANN. (Кстати, мой оригинальный подход сработал, и вы можете посмотреть историю изменений, чтобы увидеть, что это было, если вам действительно все равно).

Во-первых, для всех, кто сталкивается с этим вопросом, я должен отметить, что использовать FANN таким образом не обязательно. Сайт предоставляет файлы cmake, а также решения Visual Studio, которые отлично работают.

 

Оглядываясь назад на вопрос, проблема очевидна, и я ненавижу себя за то, что не видел ее раньше, чем через много часов. Вы заметите, что все файлы в этой команде имеют *.c расширение. Простите, что относился к вам как к новичку, но я не могу предположить, что вы что-то знаете, или я рискну дать неправильный ответ. *.c является каноническим расширением файла для С исходные файлы. Набор инструментов gnu является довольно гибким программным обеспечением, и вы Можно компилировать С код с g++ без ошибок большую часть времени. Но вы не должны, потому что вы получите эту ошибку. Так как ваш исходный файл, mushroom.c, это С Исходный файл, это будет работать для вас, чтобы просто скомпилировать код как С (в этом случае с gccне g++). Если, однако, вы используете в своей программе такие вещи, как iostream или же string или классы или любые другие C ++ код, вы правы, чтобы скомпилировать его как C ++ (условно вы можете изменить расширение на *.cpp для пояснения, но я не уверен, что GNU toolchain заботится). В этом случае, когда вы хотите включить С код в вашем C ++ программа, обязательно заверните ее в extern "C"{}, так что компилятор знает соглашения о вызовах и метки С стандарт, который не всегда совпадает с C ++ стандарт. Это означает, что не только звонки С код из C ++ без extern "C" рискует передать аргументы функциям неверным способом (хороший способ вызвать segfault), но способ, которым переменные и функции переименовываются при компиляции в сборку, различен для двух языков, поэтому вы получаете Undefined Reference на этапе компоновки, но не на этапе компиляции. В этом случае не только doublefann.c С исходный файл (который сам по себе прекрасно связывается), но также и библиотека, которая содержит объявление функции GetTickCount(), В частности, вы ссылаетесь на %SYSTEMROOT%\System32\kernel32.dll (обычно, но я считаю, что MinGW использует PATH_TO_MinGW\lib\lib32k.a), который определяет, как программы могут взаимодействовать с операционной системой Windows на уровне машинного кода. __stdcall Утилита определяется здесь, чтобы называть такие вещи, как GetTickCount() от ОС, которые являются функциями сборки, в пределах С код. Потому что это в *.dll, компилятор не может измениться __stdcall в соответствии с C ++ coventions. Это связано с тем, что «dll«обозначает»Динамически связанная библиотека«. По сути это означает, что эти файлы уже были скомпилированы в машинный код при установке Windows (или MinGW). Поэтому редактирование бессмысленно, потому что вам понадобятся глубокие рабочие знания кодов операций для каждого когда-либо созданного процессора x86_64. Таким образом звонит в С будет делать все так, чтобы __stdcall ожидает, но звонит в C ++ требует extern "C"или он искажает имена объявлений вашей функции и может вызвать ошибки во время выполнения.

ТЛ; др

FANN написано в С, С= / =C ++, так что не ожидайте C ++ компилятор, чтобы всегда компилировать С код отлично.

 

Есть два способа решить эту проблему.

1

Если вы используете C ++ функции / библиотеки, измените имя вашего исходного кода на mushroom.cpp (если хотите) и измените строку (везде, где это происходит в вашей программе)

#include "doublefann.c"

быть завернутым так:

extern "C"{
#include "doublefann.c"}

Если вы прочитали fann.h, вы могли заметить строки:

#ifdef __cplusplus //line 65
extern "C"{

#ifndef __cplusplus
} /* to fool automatic indention engines */
#endif
#endif  /* __cplusplus */

Не волнуйтесь, они не конфликтуют. Честно говоря, я не уверен, что эти строки предназначены для достижения, но я уверен, что они знают, что они делают.

2

Если mushroom.c на самом деле просто чисто С, просто скомпилируйте, используя:

gcc -o shroom.exe mushroom.c -lm -I src\ -I src\ -I src\include\ src\doublefann.c -Wall

и это должно работать. я добавил -Wall потому что мне нравится, когда я могу сделать свой код абсолютно совершенным, не стесняйтесь оставлять это, он просто печатает все ваши предупреждения.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]