在Xcode

时间:2017-08-10 19:59:29

标签: c++ ios objective-c xcode frameworks

所以,我有一个C ++项目,我想放入一个框架,它将作为C ++代码的包装器(用Objective-C / C ++编写),以便我以后可以在Swift或Objective中使用它-C项目只需将框架添加到应用程序。

到目前为止我所取得的成就:

  • 创建了所有包装器
  • 在构建阶段暴露了包装器的公共头文件
  • 在构建阶段添加了一个运行脚本,只需将所有C ++标头(保留其文件目录结构)复制到框架的目录中,以便使用该框架可供应用程序使用。我这样做的原因并不只是把它们放在标题中。构建阶段的字段是因为有很多文件和文件夹,这样做需要我将每个标题更改为#include "LocalHeader.h",而不是将其当前写为#include "CppRootFolder/Subfolder/Header.h"。此外,我宁愿不这样做,因为我想保持C ++文件不变。

问题:

除了在构建实际应用程序时,一切似乎都运行良好,xcode会错误地说它无法找到文件结构中的文件。为了说明我的意思,我有以下内容:

  • 框架的伞文件将#include "CppRootFolder/umbrella.h"(c ++伞文件)
  • 在CppRootFolder / umbrella.h中,我有几个#include "CppRootFolder/Subfolder/Header.h"
  • 每个子文件夹中的每个标头都包含从c ++代码的根文件夹引用它们的其他标头。

我对此的看法:

我似乎很清楚,问题是编译器需要从c ++代码的根文件夹中找到头文件。因此,在实际的应用程序中,在构建设置中,我添加了一个标题搜索路径:$ BUILT_PRODUCTS_DIR / FrameworkName.framework / Headers,这是我用脚本复制所有标题的地方。但是,构建失败并产生大量随机错误,无法识别已定义的类型。

关于如何让它发挥作用的任何想法?

由于

更新(日志):

<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);

1 个答案:

答案 0 :(得分:0)

当你编写包装器时,C ++不应该在外面可见。 所以#include "cppHedarFile.h"不应该在包装器外部访问,否则你会在Objective C代码中使用C ++时出错。

所以不应该有C ++标题的伞头文件。

请提供技术详细信息:您看到的复制粘贴错误消息。您对错误的解释可能会产生误导。

<小时/> 除了这一行,你没有粘贴所有内容:

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

告诉我,我是对的。 很可能你是从Objective C文件*.m中包含C ++头文件。 对于此类文件,无法访问标准C ++标头,这就是无法识别类型int32的原因。

就像我在乞讨时写的那样。在围绕C ++编写Objective C包装器时,禁止包含来自公共头文件的C ++头文件。 您只能从仅由*.mm使用的内部标头中创建*.mm文件。 这种方式包装器正在完成它们的工作,并从包装器的用户处理C ++。

<小时/> 实施例

公开标题KXSomeClass.h

@interface KXSomeClass : NSObject

@property (nonatomic, readonly) BOOL allowed;

- (NSUInteger)someAction:(NSString *)s;

@end

私人标题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

实施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