Channels ▼


Interoperating Between C++ and Objective-C

This article is the first in a series that discusses low-level details of interoperability between C, Objective-C, C++, and Objective-C++. Future installments will appear under the author's name on her new blog at Dr. Dobb's. Ed.

The example I present below, as well as all other solutions in this series, were tested on XCode 4.6.2 on the Apple LLVM 4.2 (Clang) and LLVM GCC 4.2 compilers and also on the latest XCode 5. XCode 5.0 does not contain the GCC compiler anymore, so the samples were checked only on its Apple LLVM 5.0 (Clang). When not specified otherwise, the results are the same for the latest Clang.

Calling a C++ Class Constructor with Parameters from Objective-C Code

Suppose you have a C++ class, and it has a constructor with parameters:

class CppClass {
    CppClass(int arg1, const std::string& arg2): _arg1(arg1), _arg2(arg2) { }

    // ...
    int _arg1;
    std::string _arg2;

And you have an Objective-C class, which contains the object of the previous C++ class as a member.

@interface ObjC: NSObject {
    CppClass _cppClass;

@implementation ObjC

- (id)init
    self = [super init];
    if ( self )
// What should be the syntax of call CppClass::CppClass(5, "hello") for _cppClass?
    return self;

No matter how you try to call it, you will receive a compilation error.

Solution One

Rename the source file of the Objective-C class from .m in .mm to turn it into Objective-C++ module, so you can call methods of the C++ object.

Just a few words about Objective-C++. Both GCC and Clang are able to compile source files in C++ and Objective-C. It is even possible to mix C++ and Objective-C code in one file. As the object models are different, there are some restrictions. For example, a C++ class cannot derive from an Objective-C class and vice versa. If a file has the extension ".mm"  it is considered by a compiler to be an Objective-C++ file.

In general, you cannot call a constructor with parameters for an object itself. You can only call the default constructor. There is a workaround for this limitation: Use a pointer to a C++ object instead of a C++ object. You could create the pointer using new in a method , init(), and free it in dealloc() in the Objective-C class using the delete:

@interface ObjC: NSObject {
    CppClass *_pCppClass;

- (id)init
    self = [super init];
    if ( self )
        _pCppClass = new CppClass(5, "hello");
    return self;

- (void)dealloc
    delete _pCppClass;
    [super dealloc];

This solves the problem and is the approach I recommend. There is another partial solution though, but I would not recommend using it.

Solution Two.

You can change the C ++-class as follows:

template <int X, const char Y[]>
class CPPClass
    int _x;
    const char *_string ;

template <int X, const char Y[]>
CPPClass<X, Y>::CPPClass()
 : _x(X)
 , _string(Y)

Then, the Objective-C class will become like this:

extern const char kHelloWorld[] = "hello world";

@interface ObjC : NSObject
    CPPClass<5, kHelloWorld> thing;

I don't like this approach because of its restrictions. Note that the template parameter int can be a literal, but the parameter const char [] must be declared as a variable with an external linkage (as required by Clang). Omitting the extern in the declaration yields the following compilation error: "Non-template argument refers to object 'kHelloWorld' that does not have external linkage."

The two solutions work on both Clang and GCC.


Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags


<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags


<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

