有人可以解释为什么混合我的 C 文件和 Objective-C++ 文件会导致此链接器错误吗?

Could someone please explain why mixing my C file and Objective-C++ file is causing this linker error?

所以我有几个 C 文件导入到我的 XCode 项目中。主 C 文件包含以下函数:

void myFunction (char* arg1, int arg2, int arg3, int arg4) {
    // My code here
}

然后我为此文件创建了以下头文件,将其包含在原始 C 文件和我从中调用函数的 .mm 文件中

#ifndef _HEADER_H
#define _HEADER_H

// ...

/* Function prototype */
void myFunction(char*, int, int, int);

#endif

最后,在我的 .mm 文件中,我尝试调用它:

myFunction(myString, 100, 50, 32);

我收到以下链接器错误:

Undefined symbols for architecture x86_64: "myFunction(char*, int, int, int)", referenced from: -[TestFile awakeFromNib] in TestFile.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

然而,如果我将 C 文件修改为如下所示:

void testFunction() {
     myFunction("test", 1, 2, 3);
}

void myFunction (char* arg1, int arg2, int arg3, int arg4) {
    // My code here
}

并注释掉.mm 文件中的行,它工作正常。它仅在我尝试从 .mm 文件访问 myFunction() 时发生。任何想法可能是什么原因造成的?我读过有关混合 C++ 和 Obj-C 的问题,但从来没有直接使用 C。非常感谢任何帮助。谢谢!

当你包含 c 函数时,在你的 .mm 文件中你需要使用 extern "C",像这样

extern "C" {
#    include "c-header.h"
}

或者,您可以将 extern "C" 添加到函数声明中。

这样做的原因是在 c++ 中使用名称重整来允许函数重载,真正的函数名称由编译器根据它的参数进行修改。

之所以省略参数起作用,可能是因为当函数未指定参数时,经过修饰的名称与原始名称相同。

看看任何基金会的功能原型。 它们都有前缀CF_EXTERN。 您还应该为计划在 objective-cc++objective-c++ 代码中调用的函数原型编写此前缀。 当然,使用该前缀,您将失去 c++ 的函数重载功能。