簡體   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