【问题标题】:<function> referenced from; symbol(s) not found<function> 引用自;未找到符号
【发布时间】:2011-03-05 04:26:27
【问题描述】:

我有一段从 C++ 函数中使用的 C 代码。在我的 C++ 文件的顶部有一行:#include "prediction.h"

prediction.h 我有这个:

#ifndef prediction  
#define prediction  

#include "structs.h"  

typedef struct {  
    double estimation;  
    double variance;  
} response;

response runPrediction(int obs, location* positions, double* observations,
                        int targets, location* targetPositions);

#endif

我也有prediction.c,其中有:

#include "prediction.h"  

response runPrediction(int obs, location* positions, double* observations,
                        int targets, location* targetPositions) {  
    // code here  
}

现在,在我的 C++ 文件(正如我所说的包含 prediction.h)中,我调用了该函数,然后编译(通过 Xcode)我得到了这个错误:

“runPrediction(int, location*, double*, int, location*)”,引用自:
mainFrame::respondTo(char*, int) in mainFrame.o
ld:未找到符号
collect2: ld 返回 1 个退出状态

prediction.c 被标记为针对当前目标进行编译。我对未编译的其他 .cpp 文件没有任何问题。这里有什么想法吗?

【问题讨论】:

  • 通过在代码前面加上 4 个空格来格式化代码,101010 按钮将为您完成。您可以通过用反引号包围代码来执行内联代码(cmets 中的唯一方法),因此 `some code` 变为 some code。我用反斜杠避开了以前的反引号。
  • 啊,我明白了,我想我尝试同时使用块引号和 4 个空格;难怪它不起作用。 :)

标签: c++ c xcode compiler-construction


【解决方案1】:

函数的名称很可能是mangled*。您需要执行以下操作:

extern "C" response runPrediction(int obs, location* positions,
                   double* observations, int targets, location* targetPositions);

这告诉它把它当作一个 C 函数声明。

*C++ 会在链接阶段修改函数名称以赋予它们唯一的名称,以用于函数重载。 C 没有函数重载,所以没有这样的事情。


您知道,如果您有多个要外部的东西,您也可以创建一个 extern "C" 块:

extern "C"
{
    response runPrediction(int obs, location* positions,
                   double* observations, int targets, location* targetPositions);

    // other stuff
}

就像Paul 建议的那样,要允许两者都使用标头,请使用__cplusplus 对其进行调节:

#ifdef __cplusplus
    #define EXTERN_C extern "C"
#else
    #define EXTERN_C
#endif

EXTERN_C response runPrediction(int obs, location* positions,
                   double* observations, int targets, location* targetPositions);

【讨论】:

  • 对于混合 C/C++ 项目,最好将 extern "C" {/}#ifdef __cplusplus/#endif 括起来,以便 C 和 C++ 源文件都可以#include 标头
  • @Paul:我忘记了那个细节。 :) 如果你不介意,我会添加。
  • 我不确定这是怎么回事。我输入extern "C" response runPrediction... 并收到此错误:expected identifier or '(' before string constant
  • @jfm429:那是用 C 还是 C++ 编译的? C 没有extern "C",因此预处理器定义来切换它。
  • 呵呵,条件extern 有效。是否有可能以某种方式将其编译为 C 一次,一次编译为 C++?无论如何,我把条件 ifdef 放进去,它就解决了这个问题。谢谢!
【解决方案2】:

更改 prediction.h 使其看起来像这样:

#ifndef prediction  
#define prediction  

#include "structs.h"  

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {  
    double estimation;  
    double variance;  
} response;

response runPrediction(int obs, location* positions, double* observations,
                        int targets, location* targetPositions);

#ifdef __cplusplus
}
#endif

#endif

【讨论】:

  • 如果我能接受多个答案就好了;这以及之前的答案都有帮助。谢谢大家!
【解决方案3】:

“预测”真的是 C 而不是 C++?根据文件扩展名,您将有不同的默认编译,GMan 涵盖了这一点。

如果是 C++ 并且你更改了文件名,我仍然建议 runPrediction 应该在标头中标记为 extern,它不是在本地 C++ 模块定义类 mainFrame 中定义的。

【讨论】:

    猜你喜欢
    • 2018-12-19
    • 2013-08-28
    • 1970-01-01
    • 2014-08-27
    • 2015-11-28
    • 1970-01-01
    • 2016-11-20
    • 2012-04-26
    • 2021-12-17
    相关资源
    最近更新 更多