Nickersoft
Nickersoft

Reputation: 684

Could someone please explain why mixing my C file and Objective-C++ file is causing this linker error?

So I have several C files I imported into my XCode project. The primary C file contains the following function:

void myFunction (char* arg1, int arg2, int arg3, int arg4) {
    // My code here
}

I then created the following header file for this file, including it in both the original C file and the .mm file I'm calling the function from

#ifndef _HEADER_H
#define _HEADER_H

// ...

/* Function prototype */
void myFunction(char*, int, int, int);

#endif

Finally, in my .mm file, I try calling it:

myFunction(myString, 100, 50, 32);

And I get the following linker error:

Undefined symbols for architecture x86_64: "myFunction(char*, int, int, int)", referenced from: -[TestFile awakeFromNib] in TestFile.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Yet, if I modify my C file to look like the following:

void testFunction() {
     myFunction("test", 1, 2, 3);
}

void myFunction (char* arg1, int arg2, int arg3, int arg4) {
    // My code here
}

And comment out the line in the .mm file, it works fine. It only occurs when I try to access myFunction() from the .mm file. Any ideas what might be causing this? I had read about issues with mixing C++ and Obj-C but never with just straight up C. Any help is greatly appreciated. Thanks!

Upvotes: 1

Views: 153

Answers (2)

Cy-4AH
Cy-4AH

Reputation: 4585

Look at any foundation's function prototype. They all have prefix CF_EXTERN. You should also write this prefix for function prototypes that you are planning for calling in objective-c,c++ and objective-c++ code. Of course with that prefix you will lose c++'s function overloading feature.

Upvotes: 0

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

When you include the c function, in your .mm file you need to use extern "C", something like this

extern "C" {
#    include "c-header.h"
}

or, you can just add the extern "C" to the function declaration.

The reason to do this is name mangling which is used in c++ to allow function overloading, the real function name gets modified by the compiler depending on it's arguments.

The reason why omitting the arguments work, is probably because the mangled name is the same to the original name when the function does not specify arguments.

Upvotes: 3

Related Questions