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

如何从C+;调用C函数+;iPhone中的代码?,iphone,c++,c,ios,xcode,Iphone,C++,C,Ios,Xcode,我添加了行extern“C”void perlinTest(void)到C++头,以及C头文件的包含,希望这是我所需要的,但是编译器抱怨: Undefined symbols for architecture i386: "perlinTest()", referenced from: CreateRenderer3(IResourceManager*) in Renderer.o 如果它不是库,则不需要任何外部C。我将转向.C文件扩展名以及编译器如何配置以识别它(看起来不是.

我添加了行
extern“C”void perlinTest(void)到C++头,以及C头文件的包含,希望这是我所需要的,但是编译器抱怨:

Undefined symbols for architecture i386:
  "perlinTest()", referenced from:
      CreateRenderer3(IResourceManager*) in Renderer.o

如果它不是库,则不需要任何外部C。我将转向.C文件扩展名以及编译器如何配置以识别它(看起来不是.C代码)

如果它不是库,则不需要任何外部C。我将转向.C文件扩展名以及编译器如何配置以识别它(看起来不象.c代码)

你的C++代码需要知道函数是C函数。要做到这一点,你需要用这样的方式声明:

extern "C" [prototype];
对于您的情况,一个现实的例子是:

extern "C" void perlinTest();
<>这是因为它告诉了参数的类型。在最底层,这是允许重载的:如果有两个共享相同名称的可见符号,则不可能是合法的,因此C++通过嵌入指示函数名称中参数类型的标记来允许它们。例如,<代码>void perlinTest()

但是,C不支持重载,函数不受名称限制,所以当C++代码试图调用一个时,它需要知道它不能使用被损坏的名称。

如果你的头文件需要从C和C++中读取,那么通常的做法是将它们封装在<代码>外部“C”<代码>外块(<代码>外)C“{/*声明*/} /code >”中,其本身被封装在<代码>中。


<>你的C++代码需要知道函数是C函数。要这样做,你需要用这样的方式声明:

extern "C" [prototype];
对于您的情况,一个现实的例子是:

extern "C" void perlinTest();
<>这是因为它告诉了参数的类型。在最底层,这是允许重载的:如果有两个共享相同名称的可见符号,则不可能是合法的,因此C++通过嵌入指示函数名称中参数类型的标记来允许它们。例如,<代码>void perlinTest()

但是,C不支持重载,函数不受名称限制,所以当C++代码试图调用一个时,它需要知道它不能使用被损坏的名称。

如果你的头文件需要从C和C++中读取,那么通常的做法是将它们封装在<代码>外部“C”<代码>外块(<代码>外)C“{/*声明*/} /code >”中,其本身被封装在<代码>中。


您是否在任何地方实际实施了
void perlinTest(void)

最初,您可能只需要声明函数而不需要实际实现它。如果您的其他类/对象都没有调用
perlinTest()
,Xcode将很乐意构建和运行您的应用程序,而不会发出任何错误。因为
perlinTest()
实际上不是从任何地方引用的,它不关心函数是否实际实现

当您尝试从Renderer.o中的其他类(如从
CreateRenderer3(IResourceManager*)调用
perlinTest()
)时,链接器将希望确保可以解析该符号,如果您尚未实际实现该符号的基本定义(请参见下文),那么您很可能会得到与您得到的错误相同的错误

下面这样的最小实现应该可以防止链接错误:

void perlinTest(void) {

}

您是否在任何地方实际实施了
void perlinTest(void)

最初,您可能只需要声明函数而不需要实际实现它。如果您的其他类/对象都没有调用
perlinTest()
,Xcode将很乐意构建和运行您的应用程序,而不会发出任何错误。因为
perlinTest()
实际上不是从任何地方引用的,它不关心函数是否实际实现

当您尝试从Renderer.o中的其他类(如从
CreateRenderer3(IResourceManager*)调用
perlinTest()
)时,链接器将希望确保可以解析该符号,如果您尚未实际实现该符号的基本定义(请参见下文),那么您很可能会得到与您得到的错误相同的错误

下面这样的最小实现应该可以防止链接错误:

void perlinTest(void) {

}

您可以使用的一个调试技巧是在
perlinTest()
函数中引入故意错误。然后构建您的应用程序,并查看编译器是否报告错误。如果应用程序仍在编译,则您的问题是具有此函数的文件不是您正在构建的目标的一部分

还要注意,您粘贴的错误是针对i386架构的,因此它不能是iPhone。您可能是在为iPhone模拟器构建


编辑:下一步是检查Xcode发出的link命令是否包含具有C函数的.o。如果包含,则应使用nm实用程序转储.o文件的内容,以查看.o中函数名的外观。

调试该命令的一个技巧是在
perlin中引入故意错误Test()
函数。然后构建