如何从 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()
在我的狮子盒子上被g++
(可能clang++
(破坏为_Z10perlinTestv
,尽管这是特定于 ABI 的,在其他平台上不一定相同。
但是,C 不支持重载,并且函数不受名称重整的影响,因此当您的C++代码尝试调用 one 时,它需要知道它不得使用损坏的名称。这就是extern "C"
告诉编译器的内容。
如果你的头文件需要从 C 和 C++ 读取,通常的做法是将它们包装在包装在 #ifdef __cplusplus
预处理器指令中的extern "C"
块 ( extern "C" { /* declarations */ }
( 本身(因此 C 代码看不到extern "C"
代码(。
#ifdef __cplusplus
extern "C" {
#endif
/* header body */
#ifdef __cplusplus
}
#endif
如果它不是库,则不需要任何外部 C。 我将转向.c文件扩展名以及如何配置编译器以识别它(看起来像不是.c代码(
您是否在任何地方实际实施了void perlinTest(void)
?
最初,您可能只能声明函数,而无需实际实现它。如果你的其他类/对象实际上都没有调用perlinTest()
,Xcode 将很乐意构建和运行你的应用程序,并且不会发出任何错误。由于perlinTest()
实际上并没有从任何地方引用,因此它并不关心该函数实际上没有实现。
一旦您尝试从其他类之一(例如从 CreateRenderer3(IResourceManager*) in Renderer.o
(调用 perlinTest()
,链接器就会希望确保可以解析该符号,如果您实际上还没有实现它的准系统定义(见下文(,那么您可能会收到类似您得到的错误。
如下所示的最小实现应防止链接错误:
void perlinTest(void) {
}
可用于调试此问题的一个技巧是在perlinTest()
函数中引入故意错误。然后构建应用,查看编译器是否报告错误。如果应用程序仍然编译,那么您的问题是具有此功能的文件不是您正在构建的目标的一部分。
另请注意,您粘贴的错误是针对 i386 架构的,因此它不可能是 iPhone。您可能正在为iPhone模拟器构建。
编辑:下一步是检查Xcode发出的link命令是否包含具有C函数的.o。如果是这样,那么您应该使用 nm 实用程序转储 .o 文件的内容,以查看函数名称在 .o 中的样子。
- 函数从唯一代码调用正确的子类方法
- 只允许授权代码调用库中的例程
- Android 无法从本机代码调用 Java 方法 JNI
- 如何从反应原生代码调用 C 函数?
- 如何在C++代码中使用 SVM Light?(可能无需从C++代码调用可执行文件)
- 如何从C代码调用PowerShell脚本
- 从 C 代码调用C++函数时出现问题
- 从 ObjC 代码调用 .mm 类方法时编译错误
- 代码调用反向函数不会在Ubuntu 18上的G 或Clang 上编译,但神秘地在Mac OSX上使用
- 如何使用C 代码调用MATLAB自定义函数
- 该代码调用副本或移动构造函数
- 无法在不同类上编译代码调用静态功能
- 如何从可从C++代码调用的 Ada 源代码构建静态库?
- 从 CPP 代码调用 Objective-C 方法
- 如何从C++代码调用 PL/pgSQL 函数
- C++如何判断static.lib是否有效,是否可从外部代码调用
- 当C代码调用Fortran子程序时,子程序顶部会出现分段错误
- JavaScript:从浏览器和 Node.js 中的 JavaScript 代码调用C++库
- C#到C代码P/调用多个std:字符串声明导致堆栈损坏
- 使用 Visual Studio 从C++代码调用程序集过程