繁体   English   中英

如何从iPhone中的C ++代码调用C函数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM