Channels ▼

Anna Koneva

Dr. Dobb's Bloggers

Problems When Linking Objective-C and C++ Code

February 20, 2014

This article explains problems that occur interoperating between C, Objective-C, C++, and Objective-C++ code. All the samples below 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 those examples were checked with  Apple LLVM 5.0 (based on Clang).

Calling a C++ Function from Objective-C Code

Suppose you have a C++ function, which you need to call from Objective-C code. Here are the header file and the body code:

File.h:

int DoSomethingCppFunction(int param);

File.cpp:

int DoSomethingCppFunction(int param)
{
    cout << "param = " << param << endl;
    return param;
}

If you try to call this function from the Objective-C code, you'll get a linker error that says that the symbol is not found.

Solution: This error occurs because of the C++ name mangling. To turn it off, you need to add a specifier extern "C" to the declaration of the C++ function:

#ifdef __cplusplus
extern "C" {
#endif

int DoSomethingCppFunction(int param);
    
    
#ifdef __cplusplus
}
#endif

Calling an Inline C Function from Objective-C Code

Let's say you have this code in the file main.m:

#import <Foundation/Foundation.h>

inline void foo()
{
    printf("Hello, World\n");
}

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

    foo();
        
    // insert code here...
    NSLog(@"Hello, World!");
        
    return 0;
}

Compiling this, you will get a linker error stating that the method foo is not found.

Solution: Inlined C functions are a new feature of C99/GNU99, which is turned on in the XCode project settings by default. If all of the declarations of an inline function in a module do not have a storage class specifier, then the module will not produce a callable copy of the function. This creates linker errors.

One way to fix it is to add a static modifier for the function foo. Another way is to change the C dialect to GNU89 in the settings.

Oddities While Linking an Objective-C Project for Mac OS X and a C++ Static Library

Suppose you have a static C++ library that contains the class:

FileTest.h:

public:
  Test();
  ~Test();
  int addTwoNums(int a, int b);
};

File Test.cpp:

Test::Test(){}
Test::~Test(){}

int Test::addTwoNums(int a, int b)
{
    return (a + b);
}

And you use this library in a simple console Objective-C application. If your compiler is the default Apple LLVM compiler, the result depends on which settings you use for the standard C++ library. Different combinations for using the application, library, and C++ runtime are shown below.

Case 1

app - libc++
library - libc++
Result: No linker errors.

Case 2

app - libstdc++
library - libc++
Result: No linker errors.

Case 3

app - libc++
library - libstdc++
Result: Linker errors

«Undefined symbols for architecture x86_64:
"std :: ios_base :: Init :: Init ()", referenced from:
___cxx_global_var_init in lib01SampleCppLibrary.a (Test.o)
"std :: ios_base :: Init :: ~ Init ()", referenced from:
___cxx_global_var_init in lib01SampleCppLibrary.a (Test.o)
ld: symbol (s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 
(use-v to see invocation) »

Case 4

app - libstdc++
library - libstdc++
Result: No linker errors.

Solution: Library libstdc++ is a part of GCC. It's old, and Apple has not supported GCC on Mac OS X for a long time. Although you can update it from the ports, you'll be better served by using libc++, which is newer and is supported by Apple.

Future posts will look at a few more kinds of interoperability errors between C/C++ and Objective-C.


Anna Koneva is a software engineer from Moscow, Russia. Her areas of interest and work include programming languages, especially C++, C#, and Objective-C. She develops desktop applications for Windows and mobile applications for the iPhone and iPad.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<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

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Comments:

AndrewBinstock
2014-02-25T03:09:21

Thanks for clarifying the handle, LOL!


Permalink
ubm_techweb_disqus_sso_-ff6b524456023594609a762d9f802d39
2014-02-23T13:58:40

to:Anna Koneva
re:Objective-C versus C++
Sun 2/23/2014 8:53 am

You are aware that you can write Objective C++ by using a source file with an "mm" extension? At least I could in 2011....

-- jgo, owenlabs.org

P.S. Sorry about the "jgo_stupid_dobbs"; not personal, but a memorial to their complaint that I couldn't register with a jgowen user name 'cause the nickname was already taken, presumably by me years ago with a now-Dobbs-discarded password.


Permalink


Video