简体   繁体   中英

Building a wrapper framework for C++ project in Xcode

So, I have a C++ project that I want to put into a framework that will act as a wrapper (written in Objective-C/C++) to the C++ code, so that I can later use this in a Swift or Objective-C project by simply adding the framework to the app.

What I have accomplished so far:

  • Created all the wrappers
  • Exposed the wrapper's public headers in the build phase
  • Added a run-script in the build phase to simply copy all the C++ headers (keeping their file directory structure) into the framework's directory, so that they are available to the app using the framework. The reason for me to do this and not just put them in the headers' field of the build phase is because there are a lot of files and folders and doing that would require me to change every header to #include "LocalHeader.h" rather than how it is currently written as #include "CppRootFolder/Subfolder/Header.h" . Also I would rather not do this because I want to keep the C++ files unaltered.

The problem:

Everything seems to work well except that when building the actual app, xcode will error out saying it can't find the files inside the file structure. To illustrate what I mean, I have the following:

  • The umbrella file for the framework will #include "CppRootFolder/umbrella.h" (the c++ umbrella file)
  • In CppRootFolder/umbrella.h, I have several #include "CppRootFolder/Subfolder/Header.h"
  • Each one of the headers inside each subfolder include other headers referencing them from the root folder of the c++ code.

My take on this:

It seems clear to me that the issue is that the compiler needs to find the headers from the root folder of the c++ code. So, in the actual App, in build settings, I add a header search path to: $BUILT_PRODUCTS_DIR/FrameworkName.framework/Headers, which is where I copied all the headers with the script. However, the build fails and produces a lot of random errors not recognizing types that are already defined.

Any ideas on how I can get this to work?

Thanks

UPDATE (Logs):

<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/Box2D.h"
        ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D.h:17:9: note: in file included from /Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D.h:17:
#import "World.h"
        ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/World.h:10:9: note: in file included from /Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/World.h:10:
#import "Box2D/Box2D.h"
        ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Box2D.h:34:10: note: in file included from /Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Box2D.h:34:
#include "Box2D/Common/b2Settings.h"
         ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Common/b2Settings.h:153:8: error: must use 'struct' tag to refer to type 'b2Version'
extern b2Version b2_version;
       ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/Box2D.h"
        ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D.h:17:9: note: in file included from /Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D.h:17:
#import "World.h"
        ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/World.h:10:9: note: in file included from /Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/World.h:10:
#import "Box2D/Box2D.h"
        ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Box2D.h:35:10: note: in file included from /Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Box2D.h:35:
#include "Box2D/Common/b2Draw.h"
         ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Common/b2Draw.h:22:10: note: in file included from /Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Common/b2Draw.h:22:
#include "Box2D/Common/b2Math.h"
         ^
/Users/luis/Library/Developer/Xcode/DerivedData/Project-dgathvjusrdgslfvqqcvkeqyjzcb/Build/Products/Debug-iphoneos/Box2D.framework/Headers/Box2D/Common/b2Math.h:28:31: error: unexpected type name 'int32': expected expression
        int32 ix = *reinterpret_cast<int32*>(&x);

When you write a wrappers C++ should not be visible outside. So #include "cppHedarFile.h" should not be accessible outside the wrapper, otherwise you will have an errors about using C++ in Objective C code.

So there should not be umbrella header file for C++ headers.

Please provide technical details: copy paste error message you are seeing. Your interpretation of error can be misleading.


You didn't paste everything but this line:

 /Box2D.framework/Headers/Box2D/Common/b2Math.h:28:31: error: unexpected type name 'int32': expected expression int32 ix = *reinterpret_cast<int32*>(&x); 

Give me a hind that I'm right. Most probably you are including C++ headers from Objective C file *.m . For such file C++ standard headers are not reachable that is why type int32 is not recognized.

Like I've wrote at begging. When you are writing a Objective C wrapper around C++, includes of C++ headers from public headers are forbidden. You can do it only form *.mm file for from internal headers which are only used by *.mm . This way wrappers are doing their job and handing C++ from user of wrapper.


Example

Public header KXSomeClass.h :

#import "KXSomeClass+Internal.h"

@interface KXSomeClass ()
@property (assign, nonatomic) std::shared_ptr<SomeClass> native;
@end

#import "KXSomeClass+Internal.h"
#include "cpp/SomeClass.h"

@implementation CSCapability

- (instancetype)initWithNativeSomeClass:(const std::shared_ptr<SomeClass>&)nativeObject
{
    if (self = [super init]) {
         _native = nativeObject;
    }
    return self;
}

- (NSUInteger)someAction:(NSString *)s
{
    return _native->SomeAction(s.UTF8String);
}

- (BOOL)allowed
{
    return _native->Allowed();
}

@end

Private header KXSomeClass+Internal.h

 // this header is used only by wrappers #import "KXSomeClass.h" #include <memory> @interface KXSomeClass () - (instancetype)initWithNativeSomeClass:(const std::shared_ptr<SomeClass>&)nativeObject; @end 

Implementation KXSomeClass.mm

 #import "KXSomeClass+Internal.h" @interface KXSomeClass () @property (assign, nonatomic) std::shared_ptr<SomeClass> native; @end #import "KXSomeClass+Internal.h" #include "cpp/SomeClass.h" @implementation CSCapability - (instancetype)initWithNativeSomeClass:(const std::shared_ptr<SomeClass>&)nativeObject { if (self = [super init]) { _native = nativeObject; } return self; } - (NSUInteger)someAction:(NSString *)s { return _native->SomeAction(s.UTF8String); } - (BOOL)allowed { return _native->Allowed(); } @end 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM