简体   繁体   English

C 函数总是向目标 C 返回零

[英]C function always returns zero to Objective C

I have an Objective C project incorporating a C file with some helper functions.我有一个 Objective C 项目,其中包含一个带有一些帮助函数的 C 文件。 However, functions in the C file that return a float are not working as expected.但是,C 文件中返回float函数没有按预期工作。

C file: C文件:

float returnFloat() {
    return 10.0;
}

Meanwhile in an Objective C instance method:同时在Objective C实例方法中:

float x;
x = returnFloat();

x is always 0.000000. x 始终为 0.000000。

Edit编辑

I have a bunch of "implicit declaration" warnings in the Objective C file, relating to use of the functions I have in the C file.我在目标 C 文件中有一堆“隐式声明”警告,这些警告与我在 C 文件中的函数的使用有关。

Assignments using functions that return int are working fine.使用返回int函数的赋值工作正常。 Where an assignment is made from a function returning float , the debugger says "variable optimized away by compiler".在从返回float的函数进行赋值的情况下,调试器会说“编译器优化掉的变量”。

Is it likely I'm not correctly importing the C file within the Objective-C code?我可能没有在 Objective-C 代码中正确导入 C 文件吗? I have just let Xcode link it in automagically.我只是让 Xcode 自动链接它。 Then, how come the problem only occurs for C functions that return float ?那么,为什么只有返回float C 函数才会出现问题?

You have to use a .h file, just like with .m files, to declare what you're doing in another file.您必须使用 .h 文件,就像使用 .m 文件一样,在另一个文件中声明您正在执行的操作。 So, you need something like this for this scenario (these are incomplete):因此,对于这种情况,您需要这样的东西(这些是不完整的):

returnfloat.c返回浮动.c

float returnFloat() {
    return 10.0;
}

returnfloat.h返回浮动.h

float returnFloat(void);

usefloat.m使用float.m

#import "returnfloat.h"

- (void) someMethod {
    float ten = returnFloat();
}

The problem (given away by your "implicit declaration" warnings) is that the compiler is assuming that you are calling something that returns an int or id , not a float .问题(由您的“隐式声明”警告给出)是编译器假设您正在调用返回intid东西,而不是float When you work with C, things need to be prototyped (GCC will treat the .c file like C, and all C rules apply, even though you're in an Objective-C project).当您使用 C 时,需要对事物进行原型设计(GCC 会将 .c 文件视为 C,并且所有 C 规则都适用,即使您在 Objective-C 项目中)。


If you'd like to see an example, here's something from one of my projects -- production code (you can write pure C in a file ending in .m, and GCC will treat it like Objective-C in some ways):如果你想看一个例子,这里是我的一个项目中的一些东西——生产代码(你可以在以 .m 结尾的文件中编写纯 C,GCC 在某些方面会像对待 Objective-C 一样对待它):

DebugF.m调试文件

#import "DebugF.h"

void __Debug(const char *file, int line, NSString *format, ...) {
#ifdef DEBUG
    /* Wraps NSLog() with printf() style semantics */
#endif
}

DebugF.h调试文件

#ifndef __DEBUGF_H_INCLUDED__
#define __DEBUGF_H_INCLUDED__

#ifdef DEBUG
#define DebugF(args...) __Debug(__FILE__, __LINE__, args)
#else
#define DebugF(...)
#endif /* DEBUG */

void __Debug(const char *file, int line, NSString *fmt, ...);

#endif /* __DEBUGF_H_INCLUDED */

SomeViewController.m SomeViewController.m

DebugF(@"Got these arguments: %u, %@, %@", 4, anObject, [anObject somethingElse]);

I'm no Objective-C programmer, but in C world the compiler assumes int return type for any undeclared function that current module uses.我不是 Objective-C 程序员,但在 C 世界中,编译器假定当前模块使用的任何未声明函数的返回类型为int It looks to me that creating a normal C header file containing:在我看来,创建一个普通的 C 头文件包含:


#ifndef _MY_IMPORTANT_HEADER_
#define _MY_IMPORTANT_HEADER_
extern float returnFloat();
#endif

and including that into your .m file should make it all work:并将其包含到您的 .m 文件中应该可以使其一切正常:


#include "myheader.h"

It's cause you want:这是因为你想要:

// the c way
float returnFloat() {
   return 10.0;
}

float result = returnFloat();

// the objective-c way
- (float) returnFloat {
   return 10.0;
}

float result = [self returnFloat]; // assuming this is an object

Not what you have.不是你所拥有的。 You're mixing C function prototypes with Objective-C.您将 C 函数原型与 Objective-C 混合在一起。 Try the C way mentioned above (Should be able to use it in Objective-C code).试试上面提到的C方式(应该可以在Objective-C代码中使用)。

Sorry if I misunderstood your question, I'm pretty sure my code is correct :)对不起,如果我误解了你的问题,我很确定我的代码是正确的:)

EDIT : Clarification for all of the downvoters.编辑:澄清所有反对者。 In his first revision of the post he made it float returnFloat {} instead of float returnFloat() { }, which prompted my answer.在他对帖子的第一次修订中,他将它设为 float returnFloat {} 而不是 float returnFloat() { },这促使我回答。

EDIT 2 : Apparently that wasn't clear enough.编辑 2 :显然这还不够清楚。 In his first revision of his post, he was mixing the C way of writing function prototypes with the Objective-C way of writing function prototypes.在他对帖子的第一次修订中,他将编写函数原型的 C 方式与编写函数原型的 Objective-C 方式混合在一起。 You CAN use C functions in Objective-C, but you CAN'T mix the way of writing their function prototypes, as I explained above.你可以在 Objective-C 中使用 C 函数,但你不能混合编写它们的函数原型的方式,正如我上面解释的那样。 Sorry for any confusion.很抱歉有任何混淆。

How did you declare 'returnFloat()' to your Objective-C program?您是如何向 Objective-C 程序声明“returnFloat()”的? Does it have a prototype in scope?它在范围内有原型吗? If not, then your likely problem is that Objective-C is treating the function as returning an int, not a float, and havoc ensues (or you perceive that zero is returned).如果不是,那么您可能的问题是,Objective-C 将该函数视为返回一个 int 而不是一个浮点数,并且会造成严重破坏(或者您认为返回了零)。

How are you determining that x is 0.0000 ?你如何确定x0.0000 A common mistake in debugging is to use the wrong format string in NSLog() .调试中的一个常见错误是在NSLog()使用了错误的格式字符串。

If you are, using NSLog() , make sure you're using the %f or some variant of it:如果您是,使用NSLog() ,请确保您使用的是%f或它的某些变体:

NSLog(@"x = %f", x);

(many people get mixed up and try to use %i instead) (许多人混淆并尝试使用%i代替)

EDIT: That's with the assumption that your C function prototype is correct and the lack of parentheses was just a typo here.编辑:这是假设你的 C 函数原型是正确的,缺少括号只是这里的一个错字。 If not, Blaenk's answer is likely correct.如果不是,Blaenk 的回答可能是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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