[英]How do you call a C function from C++ code in the iPhone?
我添加了行extern "C" void perlinTest(void);
到C ++头文件以及c头文件的包含,希望这是我所需要的,但编译器抱怨:
Undefined symbols for architecture i386:
"perlinTest()", referenced from:
CreateRenderer3(IResourceManager*) in Renderer.o
您的C ++代码需要注意该函数是C函数。 为此,您需要这样声明:
extern "C" [prototype];
一个适合您情况的实际示例是:
extern "C" void perlinTest();
这样做的原因是C ++函数名称被修饰为某种能说明参数类型的东西。 从最低层次上讲,这就是允许重载的地方:拥有两个相同名称的可见符号永远是不合法的,因此C ++可以通过在功能名称中嵌入表示参数类型的标记来允许它们重载。 例如, void perlinTest()
在我的Lion盒上使用g++
(可能还有clang++
)被_Z10perlinTestv
为_Z10perlinTestv
,尽管这是ABI特定的,在其他平台上不一定相同。
但是,C不支持重载,并且函数不受名称修饰的约束,因此,当您的C ++代码尝试调用一个名称时,它需要知道它一定不能使用修饰的名称。 这就是extern "C"
告诉编译器的内容。
如果您的头文件需要同时从C和C ++读取,通常的做法是将它们包装在本身包含在#ifdef __cplusplus
预处理程序指令中的extern "C"
块( extern "C" { /* declarations */ }
)中(因此C代码看不到extern "C"
代码)。
#ifdef __cplusplus
extern "C" {
#endif
/* header body */
#ifdef __cplusplus
}
#endif
如果它不是库,则不需要任何externC。我将转向.c文件扩展名,以及如何将编译器配置为识别它(看起来像不是.c代码)
您实际上在任何地方实现了void perlinTest(void)
吗?
最初,您可能仅可以声明函数而无需实际实现它。 如果您的其他类/对象perlinTest()
实际调用perlinTest()
,则Xcode将很乐意构建和运行您的应用程序,并且不会发出任何错误。 由于perlinTest()
实际上并未从任何地方引用,因此它并不在乎该函数并未真正实现。
尝试从其他类之一(例如从CreateRenderer3(IResourceManager*) in Renderer.o
调用perlinTest()
,链接器将要确保可以解析该符号,并且如果您实际上没有实现了它的准系统定义(请参见下文),那么您可能会收到与所得到的错误类似的错误。
像下面这样的最小实现应可防止链接错误:
void perlinTest(void) {
}
您可以用来调试此错误的一个技巧是在perlinTest()
函数中引入一个故意的错误。 然后构建您的应用程序,并查看编译器是否报告错误。 如果应用程序仍然可以编译,则您的问题是具有此功能的文件不属于您正在构建的目标。
另请注意,您粘贴的错误是针对i386体系结构的,因此不能是iPhone。 您可能正在为iPhone模拟器构建。
编辑 :下一步将检查Xcode发出的链接命令是否包含具有C函数的.o。 如果是这样,则应使用nm实用程序转储.o文件的内容,以查看函数名称在.o中的样子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.