Include C++ header file in Swift

2019-04-02 15:06发布

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.

1条回答
爷的心禁止访问
2楼-- · 2019-04-02 15:31

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.

查看更多
登录 后发表回答