dayhacker
dayhacker

Reputation: 63

C Code Link Errors with an iPhone App

I am having link errors when integrating a small number of C source files into an objective-c iOS project.

The C files were given to me by another developer who successfully used the code in c projects and in python projects.

When I add the c source code into the XCode project, the code compiles, but I get link errors after adding code in the objective c files to reference to C code. I get "duplicate symbol errors" for variables in the C code. This is when the objective c code has the .m extension.

When I change the objective c file to the .mm extension, I get "symbols not found for architecture i386" errors for the C functions I am calling from the objective c code.

There are many questions about C and objective C on forums, and I haven't found a solution yet. Any quick things to check?

Code snippets:

File: res.h

float Max_Std_Amp = 50;
void RD_Dispose(void);

File: res.c
void RD_Dispose(void) {
   Max_Std_Amp = 0;
}


File: Import.mm
#import "res.h"
void process(UInt32* data, UInt32 dataLength)
{
    RD_Dispose();
}

Link errors:

When Import.m has a .m extension:

duplicate symbol _Max_Std_Amp in:
    /Users/dayhacker/Library/Developer/Xcode/DerivedData/My_Project-dbvpktweqzliaefgbqbebtdgyrey/Build/Intermediates/My Project.build/Debug-iphonesimulator/Respitory Rate.build/Objects-normal/i386/Import.o

When Import.mm has a .mm extension:

Undefined symbols for architecture i386:
 "RD_Dispose()", referenced from:
 process(unsigned long*, unsigned long) in Import.o

Upvotes: 1

Views: 232

Answers (1)

trojanfoe
trojanfoe

Reputation: 122449

res.h:

float Max_Std_Amp = 50;

That should be:

extern float Max_Std_Amp;

and the actual float defined in a source file (res.c):

float Max_Std_Amp = 50;

Otherwise Max_Std_Amp will be part of every source module that includes res.h, which is not what was intended.

If you want to use a C-function from C++ (.mm is Objective-C++), you need to declare the function as having C-linkage, like this:

res.h:

#ifdef __cplusplus
extern "C" {
#endif

void RD_Dispose(void);

#ifdef __cplusplus
}  // extern "C"
#endif

The above use of guard macros and C-linkage definition will allow the res.h header file to be included in both C and C++ (Objective-C and Objective-C++) source modules.

Upvotes: 1

Related Questions