Include C++ header file in Swift
Asked Answered
A

1

6

I have a C++ header file (named header.h) which I want to include into my Swift project.

Since the C++ framework I want to include is not finished yet I just have the header file for now.

My C++ header file header.h looks a little like this:

#include <vector>

struct someStruct{
    float someAttr;
}

class someClass{
    public:
        enum SomeEnum{
            Option1,
            Option2
        }

        void someFunc(const double value) {}
}

Problem is, when I try to include the header.h file in the project-Bridging-Header.h it will never find vector which I include in header.h

'vector' file not found

I tried renaming header.h to header.hpp. I tried setting the bridging headers Type to C++ Header in the right panel. But none of them helped.

I hope some of you can help me figure out what I am doing wrong.

Arson answered 14/6, 2016 at 6:27 Comment(4)
Have you tried this?Inspiration
I have tried adding a wrapper although this would lead to a loss in classes which I need to be able to use in Swift CodeArson
Check this answer https://mcmap.net/q/166357/-can-i-mix-swift-with-c-like-the-objective-c-mm-files , hope this helps. :)Shoon
Thanks for the hint. Unfortunately the problem with all these answer out there, is that they won't give me the opportunity to use classes I defined in C++. I will only be able to wrap methods so this will result in static functions which don't help too much.Arson
B
6

Unfortunately, it is not possible to use a C++ class in Swift directly, see https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216-CH2-ID0:

You cannot import C++ code directly into Swift. Instead, create an Objective-C or C wrapper for C++ code.

Actually, a convenient way of wrapping C++ for use in Swift is Objective-C++. Objective-C++ source files can contain both Objective-C and C++ code, mixed. Here is a quick partial example based on the code snippet in your question. Only someClass is partially wrapped here. In production code you would also need to consider memory management.

The wrapper's header file, mywrapper.h, has no traces of C++:

#ifndef mywrapper_h
#define mywrapper_h

#import <Foundation/Foundation.h>

// This is a wrapper Objective-C++ class around the C++ class
@interface someClass_oc : NSObject

-(void)someFunc:(double)value;

@end

#endif /* mywrapper_h */

Here is the Objective-C++ implementation, mywrapper.mm. Please note the .mm extension. You can create an Objective-C file with an .m and then rename it.

    #import "mywrapper.h"
    #import "header.h"  // CAN import a C++ header here, in Objective-C++ code

    // Use an extension on someClass_oc because we need to use someClass,
    // but we couldn't do it in mywrapper.h,
    // which is visible from Swift and thus can't contain C++ stuff.
    @interface someClass_oc ()
    {
        someClass * ptrSomeClass;
    }
    @end

    @implementation someClass_oc

    -(id)init
    {
        // In this example ptrSomeClass is leaked...
        ptrSomeClass = new someClass();
        return self;
    }

    -(void)someFunc:(double)value
    {
        ptrSomeClass->someFunc(value);
    }

    @end

Now you can import mywrapper.h in the bridging header and then do something like this in Swift:

let x = someClass_oc()

x.someFunc(123.456)

Thus you can create an object in Swift, which is backed by an instance of your C++ class.

This is just a quick example to give you an idea. If your run into other problems, they would probably deserve separate questions.

Bb answered 17/6, 2016 at 3:16 Comment(1)
thanks for your detailed answer. I probably need to wrap the classes and its function completely or rewrite the framework in swift.Arson

© 2022 - 2024 — McMap. All rights reserved.