views:

42

answers:

2

Hi guys,

I'm converting my App Delegate file from .m to .mm (Objective-C to Objective-C++) so that I can access a third-party library written in Objective-C++. In Objective-C, my app delegate builds and runs fine. But when I change the extension, the project builds and I get link errors, all of which are missing symbols from a static library written in C that I use. The errors are classic link errors with the following format:

"MyFunction(arguments)", referenced from:

-[MyAppDelegate myMethod] in MyAppDelegate.o

Symbol(s) not found

All of the problems are in the app delegate object. I know that I'm all set to compile Objective-C++ because my ViewController file is .mm. So my question has a few parts to it.

First, are these symbols truly not there in the sense that I can't use them? In other words, is it not possible to access plain old C functions from an Objective-C++ file? If this is true, that's pretty unfortunate. I thought that almost all Objective-C code, and certainly all Objective-C code that at least builds as .mm, was valid Objective-C++. Am I wrong?

If not, any idea how I can prevent these errors? Are there header rules that are different in Objective-C++ that I don't know about?

Thanks for any and all help.

+2  A: 

Link errors with mixed C++/C or C++/Objective-C programs are usually due to C++ name mangling. Make sure you have extern "C" attached to all the appropriate declarations, and also that all of your code agrees on the linkage. That is, make sure that the function definition as well as the places where it is used can all see the extern "C" or extern "C++".

In your particular situation, it looks like MyFunction() is getting compiled with C++ linkage and having its name mangled, but that your myMethod Objective-C file is trying to link against the unmangled name.

Here is a link to the wikipedia article about name mangling.

Carl Norum
Excellent, much appreciated.
Luke
+1  A: 

Surround your header include with extern C.

This tells the linker that the function names in the library do not get C++ name mangling.

E.g.:

 extern "C" {
   #include "my-lib.h"
 }
tpdi
Include this in the header, not around the #include.
tc.
tc, why would he pollute the header when he doesn't need to?
tpdi
@tpdi: so that he can use it in any C++ source file without polluting the source file. Of course, he'll have to surround the `extern "C"{` and `}` with `#ifdef __cplusplus` so it will still compile in C.
JeremyP