繁体   English   中英

为C ++库制作Objective-C包装器

[英]Making a Objective-C Wrapper for a C++ Library

我试图在Objective-C中创建一个包装器,所以我不必在库类之外编写c ++。

Library主文件是LLAHProcessor.h .cpp

我的包装器是LLAHProcessorWrapper.h .mm

它编译得很好,但是当我将LLAHProcessorWrapper添加到其他类(让我们说UIView)作为成员变量时,我得到了数百个错误,例如:

#include <map> : Map no such a file or directory

在每个c ++类/结构中:

Expected specifier-qualifier list before ClassName

就像编译器没有识别c ++代码一样。

我想知道我在这里失踪了什么。 是否必须将我添加到Xcode Target Properties的事实:?

Other Link Flags : -lstdc++ -lz

或者我可能需要在这里添加新标志?

提前致谢

您的问题是.m文件被编译为C而不是C ++。 因此,当编译器在编译.m文件时,即使在头文件中遇到任何C ++,它也会barf。

毫无疑问,你必须在头文件中加入一些C ++,因为Objective C对象包装了一个C ++对象,但是有很多方法可以解决这个问题。 一种方法是使用指向C ++对象的指针,并使用方便的预处理器定义__cplusplus ,它是为C ++(和Objective-C ++)定义的,但不是为C(或Objective-C)定义的,例如

// LLAHProcessorWrapper.h

#if defined __cplusplus
class MyCPPClass;    // forward class declaration
#else
typedef struct MyCPPClass MyCPPClass;   // forward struct declaration
#endif

@interface MyOCClass : NSObject
{
@private
    MyCPPClass* cppObject;
} 

// methods and properties

@end

由于您永远不会取消引用.mm文件之外的.mm成员,因此您永远不会为结构提供完整定义。

您将new并分别delete -init-dealloc的指针。 您将在LLAHProcessorWrapper.mm包含完整的C ++类声明。

您需要做的就是创建一个.mm ,编译器应该处理所有事情。

需要注意的是,在.h文件中有任何与C ++相关的东西是不安全的,因为它们可以/将被其他仅使用Objective-C的文件导入,然后一切都会崩溃。 这里的主要问题是你不能直接将C ++类型定义为Objective-C包装类的实例变量,除非每个.m文件都被重命名为Objective-C ++ .mm文件。

解决方案是在头文件中将实例变量定义为void* ,并从实现文件中使用类型转换来访问它们。 最简单的解决方案是使用为您进行类型转换的私有属性来访问实例变量。

假设FooFoo.h定义的C ++类的示例代码:

// FooWrapper.h
#import <Foundation/Foundation.h>

@interface FooWrapper : NSObject {
@private
  void* foo;
}
// Actual wrapper API for Foo…
@end


// FooWrapper.mm
#import "FooWrapper.h"
#include <map>
#include "Foo.h"

@interface FooWrapper ()
@property(nonatomic, assign) Foo* foo;
@end

@implementation FooWrapper
-(Foo*)foo {
  return (Foo*)foo;
}
-(void)setFoo:(Foo*)aFoo {
  foo = (void*)aFoo;
}
// Implementation of actual API for Foo…
@end

在任何要引用LLAHProcessorWrapper头文件( .h )中,使用正向类定义而不是导入,如下所示:

@class LLAHProcessorWrapper;
@interface SomeView : UIView {
  LLAHProcessorWrapper *wrapper;
}

并确保相应的实现文件具有#include LLAHProcessorWrapper.h#import LLAHProcessorWrapper.h

如果LLAHProcessorWrapper.h整个包含树中的任何其他内容都具有任何C ++语法,则#include#import标头的任何实现文件都必须具有.mm作为其后缀。 这样,有一个.mm文件倾向于意味着代码库的大部分必须将其文件重命名为.mm

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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