Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wrap a C++ lib in objective-C?

I have a C++ library (.h only) that contains the implementation of a data structure and I'd like to use it in my iPhone app.

Firstly, I wrote a wrapper in objective-C++ as a class that, through composition, has an ivar of the C++ class. I then was 'obliged' to change the wrapper class extension to .mm, and it seemed fine. But then I have to include this wrapped class file into several other files, so I have to change their extension too (in order to prevent a wave of compile-time errors).

Am I correct? Is there a way to 'confine' the .mm extension to just few files?(and so preventing name clashes etc)

EDIT: Some more info that might help, I'm using LLVM 1.5 as the compiler (I noticed that the number of compile time errors varies from GCC 4.2 to LLVM 1.5 but I'm not sure that it means much, since I didn't have a look at them all)

like image 791
rano Avatar asked Dec 22 '22 22:12

rano


2 Answers

My recommendation is to wrap the C++ bits in #ifdefs:

//MyWrapper.h

#ifdef __cplusplus
class ComposedClass;
#endif 

@interface MyWrapper : NSObject
{
#ifdef __cplusplus
ComposedClass *ptr;
#endif
}

// wrapped methods here...
@end

This is a slightly lame version of the PIMPL idiom, but less code, and effective for hiding C++-isms from your pure Objective-C code. Obvioulsy you would have to include the ComposedClass's header in your MyWrapper.mm.

If ComposedClass is a templated type, you will need to modify the first block to

#ifdef __cplusplus
#include "ComposedClass.h"
#endif

instead of using a forward declaration and then, of course, use the templated type in your Objective-C class' instance variable declaration.

This approach was suggested by Greg Parker, the runtime guru at Apple.

like image 74
Barry Wark Avatar answered Jan 02 '23 14:01

Barry Wark


Any code that includes a C++ snippet (no matter how small) must be compiled with Objective-C++ (and hence be in a .mm file). If you want to narrow down the number of .mm files, you would have to wrap the functionality of your C++ code in an Objective-C class so that this class's public interface (its .h file) only consists of Objective-C code. That means the wrapper class must not contain a public ivar of a C++ type. Whether this is a feasible approach if your C++ lib only consists of a data structure, I don't know.

Note that AFAIK LLVM 1.5 does not include C++ support yet (only LLVM 2.0 does). AFAIK, when you select LLVM 1.5, Xcode will automatically switch to GCC for all C++/Objective-C++ files.

like image 29
Ole Begemann Avatar answered Jan 02 '23 15:01

Ole Begemann