如何使C函数和预处理器宏可用于多个Objective-C类?

时间:2021-05-22 19:59:04

I have a C function and a macro:

我有一个C函数和一个宏:

double degreesFromRadians(double radians) { return (radians * 180.0 / M_PI ) ;
#define FPROUND(doubleA, doubleB) round( (doubleA) * pow(10.0,doubleB))

which I use in one of my Objective-C model classes. I also would like them to be available in my unit Test class for some additional tests not related to the model class.

我在我的一个Objective-C模型类中使用它。我也希望它们可以在我的单元测试类中用于一些与模型类无关的其他测试。

Not wanting to duplicate the code, I tried to put it into a separate MyAppMathFunctions.c file and to #import it into the model class.

我不想复制代码,我试着把它放到一个单独的MyAppMathFunctions.c文件中,然后#import到模型类中。

Now building the app with Xcode (version 7.0) fails with a linker error:

现在使用Xcode(版本7.0)构建应用程序失败,并显示链接器错误:

duplicate symbol _degreesFromRadians in MyAppMathFunctions.o  and ...modelClass.o  

Needless to say, because of that failure, I didn't go on to putting the #import MyAppMathFunctions.c into my unit test class, as I had originally planned.

毋庸置疑,由于失败,我没有继续将#import MyAppMathFunctions.c放入我的单元测试类中,就像我原先计划的那样。

What am I doing wrong?

我究竟做错了什么?

1 个解决方案

#1


3  

Moving this code to a C file is not a good approach, because C files are not meant to be included in other translation units. Doing this creates duplicate symbols, but more importantly, it creates confusion among the readers of your code.

将此代码移动到C文件不是一个好方法,因为C文件不应包含在其他翻译单元中。这样做会创建重复的符号,但更重要的是,它会在代码的读者之间造成混淆。

One approach to solving this problem would be placing the definition into a header file with an inline modifier, and then providing a definition of the function in exactly one translation unit by using the extern declaration:

解决此问题的一种方法是将定义放入带有内联修饰符的头文件中,然后使用extern声明在一个转换单元中提供函数的定义:

appmath.h:

#define FPROUND(doubleA, doubleB) round( (doubleA) * pow(10.0,doubleB))
inline double degreesFromRadians(double radians) {
    return (radians * 180.0 / M_PI );
}

appmath.c

#include "appmath.h"
extern double degreesFromRadians(double radians);

This way the body of your function would remain available to the compiler for inlining in all translation units, and there would be no duplicate symbols when your code is linked.

这样,函数体可供编译器继续使用,以便在所有转换单元中进行内联,并且在链接代码时不会出现重复的符号。

#1


3  

Moving this code to a C file is not a good approach, because C files are not meant to be included in other translation units. Doing this creates duplicate symbols, but more importantly, it creates confusion among the readers of your code.

将此代码移动到C文件不是一个好方法,因为C文件不应包含在其他翻译单元中。这样做会创建重复的符号,但更重要的是,它会在代码的读者之间造成混淆。

One approach to solving this problem would be placing the definition into a header file with an inline modifier, and then providing a definition of the function in exactly one translation unit by using the extern declaration:

解决此问题的一种方法是将定义放入带有内联修饰符的头文件中,然后使用extern声明在一个转换单元中提供函数的定义:

appmath.h:

#define FPROUND(doubleA, doubleB) round( (doubleA) * pow(10.0,doubleB))
inline double degreesFromRadians(double radians) {
    return (radians * 180.0 / M_PI );
}

appmath.c

#include "appmath.h"
extern double degreesFromRadians(double radians);

This way the body of your function would remain available to the compiler for inlining in all translation units, and there would be no duplicate symbols when your code is linked.

这样,函数体可供编译器继续使用,以便在所有转换单元中进行内联,并且在链接代码时不会出现重复的符号。