HOME

HOWTO: Use a C++ Library from Swift

Swift is an exciting new programming language combining the best of older languages such as Java, C++, Objective-C, JavaScript etc. However, huge code bases exist that are written in C and C++. What if you have a library developed in C++ and want to leverage that code in you Swift applications? Here we will see how to incorporate a simple C++ library into a trivial Swift command line utility on Mac OS X. We are going to

Here it's assumed that you know the basics of using Xcode, Mac OS X Terminal command line, and programming in Swift, C, and C++.

Create a Swift Command Line Utility in Xcode

First we are going to create a simple command line utility in Swift using Xcode. We could have created a more sophisticated GUI app, but since the focus here is on interfacing Swift with C++ code, a command line utility will suffice.
  1. In Xcode go to File->New->Project, in the dialog that appears select Command Line Tool and click Next.
  2. Choose a name for your project and type it in the Product Name field in the next dialog; make sure Swift is selected in the Language field. For the purposes of this tutorial let's call it cli_swift. Click Next.
  3. In the dialog that appears select a location for your project and click Create. The resulting project should consist of one Swift source file, main.swift, which contains: import Foundation println("Hello, World!") We can comment out or remove the "import Foundation" line, since we are not using any of the Foundation features.
  4. Now we can run our project by clicking the Run button from the toolbar, selecting Run from the Product menu, or by typing Command-R. We see "Hello, World!" printed out in the output pane.

Create a C++ Library Using GCC

Now let's build a simple C++ static library. We could have done it in Xcode, but let's just use a command line compiler, GCC. The command for compiling/linking C++ code is g++. You can also use the Clang compiler that should come with your Mac OS X, in which case replace g++ with clang++ in the example.
  1. Choose a location for the library and cd to that directory.
  2. Create the header file for the library, let's call it junk.h, with the following content: class A { public: A(int); int getInt(); private: int m_Int; };
  3. Create the library's implementation file, call it junk.cpp, with the following content: #include "junk.h" A::A(int _i) : m_Int(_i) {} int A::getInt() { return m_Int; }
  4. Compile junk.cpp to object file, junk.o, and create a library, named libjunkcpp.a, that contains the object file ($ is the command prompt of the Terminal): $ g++ -c junk.cpp $ ar r libjunkcpp.a junk.o

Add C++ Wrapper to the Xcode Project to Provide the Swift-C++ Interface

Now that we have our library, let's go back to Xcode and create a C++ file providing the "glue" between our C++ library and command line utility written in Swift. The "glue" has to be in C++ because it will call C++ library code that was not written to be called from C. The "glue" is, however, written in such a way that it can be called from C code, and things that can be called from C can typically be also called from Swift. See the comments in the code below.
  1. Add the static C++ library to the Xcode project. We need this in order to be able to call the library from the C++ wrapper ("glue"). Please see here how to do this.
  2. Add the library's header file, junk.h, to our project by going to File->Add Files to "cli_swift"..., navigating to the file, and clicking Add.
  3. Go to File->New->File, select C++ file in the dialog that appears, and click Next.
  4. Type wrapper.cpp in the Name field, uncheck "Also create a header file," and click Next.
  5. In the dialog that appears choose a location for the new file and click Create.
  6. If at this point Xcode suggests that you create a bridging header, click Yes. Otherwise we can create a bridging header manually by going to the "Swift Compiler - Code Generation" section under Build Settings and specifying a header name on the "Objective-C bridging Header" line.
  7. Modify wrapper.cpp to have the following content: #include "junk.h" // extern "C" will cause the C++ compiler // (remember, this is still C++ code!) to // compile the function in such a way that // it can be called from C // (and Swift). extern "C" int getIntFromCPP() { // Create an instance of A, defined in // the library, and call getInt() on it: return A(1234).getInt(); }

Use C++ from Swift Code via the Wrapper

Now we need to tell Swift about the getIntFromCPP() method. Any C functions that we want to call from Swift must be declared in the bridging header, so we add the following to the bridging header: int getIntFromCPP(); Now we can call the method from Swift by adding the following to main.swift: println("The integer from C++ is \(getIntFromCPP())") Run the project, and the output is: Hello, World! The integer from C++ is 1234 That's it! Congratulations! You have just written a Swift app that uses an external static library written in C++. Below is a screenshot of what your Xcode project might look like: Screenshot of the Xcode project.

Please don't hesitate to contact me with questions or comments.

© 2015 swiftprogrammer.info