g ++ - 查找适当的Windows库进行链接以编译FANN库

时间:2016-02-07 22:49:11

标签: c++ compilation fann

出于各种原因,我一直在尝试自己编译FANN库。我在使用MinGW的Windows 10上。为了简单起见,我打算开始这样的事情:

mushroom.c

<stdio.h>包括"fann.h"-I src\ -I src\include\ src\doublefann.c。)

使用doublefann.c:(.text+0x4ee9): undefined reference to GetTickCount() 允许我摆脱由于找不到头文件而导致的各种未定义的引用错误,但它现在不断抛出以下未定义的引用:

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

仅供参考,这出现在fann.h(第54行):

href

简而言之,链接Windows库似乎是一个错误,我真的不知道如何继续,以便找到相关的链接。

以下是完整的fann.h和完整的doublefann.c

1 个答案:

答案 0 :(得分:3)

免责声明和说明

编辑:自昨晚上床以来,我改进了我的方法,因此您无需编辑实际的FANN源文件。 (为了记录,我的原始方法有效,您可以查看编辑历史记录,看看如果您真正关心的是什么)。

首先,对于任何绊倒这个问题的人,我应该注意到这种方式并不一定非常需要使用FANN。该网站提供了cmake文件以及可以正常工作的Visual Studio解决方案。

错误

回顾这个问题,问题是显而易见的,我讨厌自己没有在第一个太多小时之前看到它。您会注意到该命令中的所有文件都具有*.c扩展名。请原谅我像新手一样对待你,但我不能假设你知道任何事情,或者我冒着给出错误答案的风险。 *.c C 源文件的规范文件扩展名。 gnu工具链是一个相当灵活的软件,你可以编译 C 代码g++,大部分时间都没有错误。但你不应该,因为你会得到这个错误。由于您的源文件mushroom.c C 源文件,因此您可以将代码编译为 C (在本例中为{ {1}},而不是gcc)。但是,如果您在程序中使用g++iostream或类或任何其他 C ++ 代码中的内容,则可以将其编译为 C ++ (按照惯例,您可以将扩展名更改为string以进行说明,但我不确定GNU工具链是否关心)。在这种情况下,只要您想在 C ++ 程序中包含 C 代码,请务必将其包装在*.cpp中,以便编译器知道调用约定和标签是 C 标准,它并不总是与 C ++ 标准相同。这意味着不仅从 C ++ 调用 C 代码而没有extern "C"{}冒险以错误的方式将参数传递给函数(导致段错误的好方法),编译为汇编时变量和函数重命名的方式在两种语言之间是不同的,这就是为什么在链接阶段得到extern "C"而不是编译阶段。在这种情况下,不仅Undefined Reference C 源文件(它本身链接正常),但包含doublefann.c的函数声明的库也是如此。具体来说,您正在链接到GetTickCount()(通常,但我相信MinGW使用%SYSTEMROOT%\System32\kernel32.dll),它定义了程序如何在机器代码级别与Windows操作系统进行交互。此处定义了PATH_TO_MinGW\lib\lib32k.a实用程序,用于在操作系统中调用__stdcall之类的内容,它们是 C 代码中的汇编函数。因为它位于GetTickCount()中,所以编译器无法更改*.dll以适应 C ++ 协议。这是因为“__stdcall”代表“动态链接库”。从本质上讲,这意味着在安装Windows(或MinGW)时,这些文件已经编译成机器代码。所以编辑它是没有意义的,因为你需要对每个x86_64处理器的操作码都有熟悉的工作知识。因此,调用 C 将以dll期望的方式执行所有操作,但调用 C ++ 需要__stdcall,否则它将会崩溃函数声明的名称,可能导致运行时错误。

TL;博士

FANN用 C C = / = C ++ 编写,所以不要指望 C ++ 编译器总是完美地编译 C 代码。

解决方案

有两种方法可以解决这个问题。

1

如果您正在使用 C ++ 功能/库,请将源代码的名称更改为extern "C"(如果需要)并更改行(在程序中的任何位置)

mushroom.cpp

像这样包裹:

#include "doublefann.c"

如果您阅读fann.h,您可能已经注意到了这些行:

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

别担心,这些似乎没有冲突。坦白说,我不确定这些线是什么意思,但我相信他们知道他们在做什么。

2

如果#ifdef __cplusplus //line 65 extern "C" { #ifndef __cplusplus } /* to fool automatic indention engines */ #endif #endif /* __cplusplus */ 真的只是纯 C ,只需使用以下代码进行编译:

mushroom.c

这应该有效。我添加了gcc -o shroom.exe mushroom.c -lm -I src\ -I src\ -I src\include\ src\doublefann.c -Wall ,因为我喜欢能够让我的代码绝对完美,随意留下它只是打印出你可能拥有的每一个警告。