我将行extern "C" void perlinTest(void);
添加到C ++标题以及c头文件的包含中,希望这是我所需要的但是编译器抱怨:
Undefined symbols for architecture i386:
"perlinTest()", referenced from:
CreateRenderer3(IResourceManager*) in Renderer.o
答案 0 :(得分:1)
您的C ++代码需要知道该函数是C函数。为此,您需要以这种方式声明:
extern "C" [prototype];
您的情况的一个现实例子是:
extern "C" void perlinTest();
这样做的原因是C++ function names are mangled告诉了参数的类型。在最低级别,这是允许重载的原因:拥有两个共享相同名称的可见符号从来都不合法,因此C ++通过嵌入指示函数名称中参数类型的标记来允许它们。例如,void perlinTest()
在我的Lion框中被_Z10perlinTestv
与g++
(可能是clang++
)混淆为extern "C"
,尽管这是ABI特定的,并且不一定相同其他平台。
但是,C不支持重载,并且函数不受名称修改的影响,因此当您的C ++代码尝试调用它时,它需要知道它不能使用损坏的名称。这是extern "C"
告诉编译器的内容。
如果您的头文件需要可以从C和C ++中读取,通常的做法是将它们包装在extern "C" { /* declarations */ }
块(#ifdef __cplusplus
)本身包装在extern "C"
预处理器指令中(因此C代码没有看到#ifdef __cplusplus
extern "C" {
#endif
/* header body */
#ifdef __cplusplus
}
#endif
代码)。
{{1}}
答案 1 :(得分:0)
如果它不是库,则不需要任何extern C.我将转向.c文件扩展名以及编译器如何配置识别它(看起来不像.c代码)
答案 2 :(得分:0)
您是否实际在任何地方实施了void perlinTest(void)
?
最初,您可能只需要声明该函数而无需实际执行它。如果您的其他类/对象都没有实际调用perlinTest()
,Xcode将很乐意构建并运行您的应用程序,而不会发出任何错误。由于perlinTest()
实际上并未从任何地方引用,因此并不关心该函数是否实际实现。
只要您尝试从其他类(例如perlinTest()
)调用CreateRenderer3(IResourceManager*) in Renderer.o
,链接器就会确保可以解析符号,如果没有实际上实现了它的准系统定义(见下文),然后你可能会得到一个像你得到的错误。
如下所示的最小实现应该可以防止链接错误:
void perlinTest(void) {
}
答案 3 :(得分:0)
您可以用来调试此问题的一个技巧是在perlinTest()
函数中引入故意错误。然后构建您的应用程序,看看编译器是否报告错误。如果应用程序仍在编译,那么您的问题是具有此功能的文件不是您正在构建的目标的一部分。
另请注意,您粘贴的错误是针对i386架构的,因此它不能是iPhone。你可能正在构建iPhone模拟器。
编辑:下一步是检查Xcode发出的链接命令是否包含具有C功能的.o。如果是,那么你应该使用nm实用程序转储.o文件的内容,以查看.o中函数名称的含义。