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:
#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:
#include "CppRootFolder/umbrella.h"
(the c++ umbrella file) #include "CppRootFolder/Subfolder/Header.h"
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.
/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.
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.