views:

501

answers:

1

hej.h

void hej();

hej.m

void hej(){}

main.mm

#import "hej.h"

int main(int argc, char *argv[])
{

}

This gives me:

"hej()", referenced from: _main in main.o symbol(s) not found

If I rename main.mm to main.m (single m), or hej.m to mm or cpp, then it works. (Though none of those "solutions" are preferable. Imagine you want to use a c-lib in a objc++ environment - you wouldn't wanna change the entire lib, maybe even couldn't, and you need to use it in objc++.)

What exactly is going on here?

+8  A: 

When compiled in a C file (*.c, *.m), the declaration void hej() generates a linker reference to a C function named _hej. When compiled in a C++ file (*.cc, *.mm, etc.), the declaration generates a linker reference to a C++ 'mangled name', that includes in it a description of the arguments. (This is done to support function overloading, e.g. to differentiate void hej(int) from void hej(char*)). hej.m always creates the C name. When main.mm references the C++ name, it won't be found.

To resolve, ensure main.mm looks for a C name, not a C++ one. If you control hej.h, it's common to add something like the following, which would work when hej.h is included in either a C or a C++ file:

/* hej.h */
#ifdef __cplusplus
extern "C" {
#endif

void hej();

#ifdef __cplusplus
}
#endif

If you do not own hej.h, you could do the following in main.mm instead:

extern "C" {
#import "hej.h"
}

int main(int argc, char *argv[])
{
}
Oren Trutner