How would I wrap C++ source code to be used in Swift?

How would I wrap C++ source code to be used in Swift? I'm not even sure how to get started. What is the best approach? Would I necessarily have to compile the C++ code into a static library?

Answered by john daniel in 316258022

ShinehahGnolaum wrote:


How would I wrap C++ source code to be used in Swift? I'm not even sure how to get started. What is the best approach? Would I necessarily have to compile the C++ code into a static library?

You can't do this directly.


Most of the advice you will find says to use C as a lowest-common denominator. I don't like that approach because Swift doesn't even handle C that well.


Here is what I do:

Wrap all the C++ code you want to use into Objective-C++ classes. You probably don't need to use every method, so try to limit the busywork whenever you can. Each Objective-C++ class should inherit from NSObject or some other Objective-C++ class. In the public interface, provide access to the properties and methods you need - but no C++ data of any kind. For each Objective-C++ header "Foo.h", create a counterpart named "FooPrivate.h". Put all your C++ data into "FooPrivate.h". Your Objective-C++ source files can import any and all "Private.h" files. (Maybe "++" would be a better term instead of "Private".)


Wrap that up in a Framework and export to Swift. Maybe add a Swift header and tweak it until it looks the way you want in Swift. Write a good set of unit tests in Swift.

You cannot use C++ code directly from Swift, because Swift doesn't have support for C++ calling conventions.


You could wrap C++ code in C (or Obj-C), and that should work fine for global functions and variables. However, that won't allow interoperation of C++ classes and objects with Swift.

This previous thread same topic is 3 yrs. old, but may have info that still applies:


https://forums.developer.apple.com/message/98464#98464

Accepted Answer

ShinehahGnolaum wrote:


How would I wrap C++ source code to be used in Swift? I'm not even sure how to get started. What is the best approach? Would I necessarily have to compile the C++ code into a static library?

You can't do this directly.


Most of the advice you will find says to use C as a lowest-common denominator. I don't like that approach because Swift doesn't even handle C that well.


Here is what I do:

Wrap all the C++ code you want to use into Objective-C++ classes. You probably don't need to use every method, so try to limit the busywork whenever you can. Each Objective-C++ class should inherit from NSObject or some other Objective-C++ class. In the public interface, provide access to the properties and methods you need - but no C++ data of any kind. For each Objective-C++ header "Foo.h", create a counterpart named "FooPrivate.h". Put all your C++ data into "FooPrivate.h". Your Objective-C++ source files can import any and all "Private.h" files. (Maybe "++" would be a better term instead of "Private".)


Wrap that up in a Framework and export to Swift. Maybe add a Swift header and tweak it until it looks the way you want in Swift. Write a good set of unit tests in Swift.

Ok. Thank you.


I'll look at your explanation carefully. It will take some studying out.


I also found your old explanation at forums.developer.apple.com/message/316117#316117. I see you've answered my question in that post also. Can I assume that your answers on both questions answer the same question?

Yes. I am talking about the same thing. Full disclosure though - most people would think I'm crazy for doing this.

I don't think it's crazy, but I do think it won't be as helpful as it first seems.


If you use Obj-C++, then there are two kinds of classes: Obj-C classes and C++ classes, which don't interoperate. (Specifically, one kind of class can have members of the other kind, but there's no way of using a C++ class as a Obj-C class or vice versa.)


That means you either have to have a duplicate set of Obj-C classes, each of which wraps a single C++ class, or you have to stay away from Obj-C classes completely. The first way is fine, at the cost of writing glue code for the wrappers. The second way basically leaves you with only global functions and variables.


There may be some small advantage of using Obj-C static methods and properties instead of C globals and functions, but nowadays Swift handles both equally well.

Yes. That is all true. As I mentioned in the other thread. This is not something you would want to attempt unless you have a super-useful C++ library. In my case, I was using GDAL. So I spend 2 months writing wrappers? I'm still left with something 100 times more powerful than all of MapKit.


Also, you don't have to wrap each and every class. You could consolidate and export only the functionality you need.


And for some more full disclosure - I probably wouldn't do do this again. I did all that when Swift was relatively new and I was still interested in being marketable for employment purposes. Since then, Swift hasn't lived up to the hype. It is just trying to reimplement a clunky version of C++ at this point. My business is doing well (using Objective-C). Since I don't need to look for a job, there is no real reason for me to use Swift.

How would I wrap C++ source code to be used in Swift?
 
 
Q