我有一个c ++静态libray:.a
文件和staticLibrary.h
文件。
在.h文件中,有一个我想要访问的类:
typedef enum
{
eStaticLibOperationUnknown = 0
eStaticLibOperationSystemCheck = 1
} enumStaticLibOperation;
typedef enum
{
eStaticLibResultUnknown = 0,
eStaticLibResultNullParameter = 4,
eStaticLibResultWrongParameter = 5
} enumStaticLibResult;
typedef std::function<void(void)> typeCallBack;
class classResultHelper
{
blah blah
};
class staticLibrary
{
public:
staticLibrary(typeCallBack, const char*);
void requestOperation(const char*, size_t);
void requestOperation(enumStaticLibOperation, const char*, size_t);
enumStaticLibResult getResult(char**, size_t*);
};
我在viewController.m文件的顶部使用了#import "staticLibrary.h"
。这引起了一个错误,因为它认识到C ++是外来的。然后我将viewController更改为.mm扩展名,生成文件Objective-C ++并删除错误。
但是当我尝试在viewDidLoad中运行staticLibrary* sL = [[staticLibrary alloc] init];
时,我在右侧的第二个静态库中出现错误。它说&#34;接收器类型不是一个客观的c类&#34;。我做错了什么?
在查看使用静态库的文档时,它说:
1.1. new staticLibrary(callback, “en”);
1.2. requestOperation(“enumSystemcheck”, NULL, 0);
1.3. callback();
1.4. getResult(... , ...);"
我相信这是Java(?),第一行是用这些参数创建一个staticLibrary实例。我如何在Objective-C中做到这一点?
答案 0 :(得分:2)
示例中的代码不是Java,而是C ++。 ObjC ++意味着您可以在一行中混合使用C ++或ObjC创建的语句,这并不意味着您可以像使用ObjC对象一样使用C ++对象,也不能使用ObjC语法。
人们通常只会在.mm文件本身中包含C ++标头和编写C ++代码,而不是在标题中添加任何内容。编写一个ObjC类,它包装了你想要的C ++库部分。所以在你的例子中,这就像是:
<强> JCRStaticLibrary.h 强>
@interface JCRStaticLibrary : NSObject
-(instancetype) initWithCallback: (void(^)(void))inObjCCallback;
-(void) requestOperation: (NSString*)what withBuffer: (void*)buf size: (int)theSize;
@end
<强> JCRStaticLibrary.mm 强>
#import "JCRStaticLibrary.h"
#include "staticLibrary.h"
@interface JCRStaticLibrary ()
{
staticLibrary *_cppStaticLibrary;
}
@end
@implementation JCRStaticLibrary
-(instancetype) initWithCallback: (void(^)(void))inObjCCallback
{
self = [super init];
if( self )
{
_staticLibrary = new staticLibrary( inObjCCallback, "en"); // ObjC++ knows how to turn an ObjC block into a C++ lambda.
// Under the hood it generates code like:
// _staticLibrary = new staticLibrary( [inObjCCallback](){ inObjCCallback(); }, "en");
// Where the [inObjCCallback](){} part is how C++ does lambdas, its equivalent to blocks.
// I.e. it's roughly analogous to ObjC's ^(){}.
}
}
-(void) dealloc
{
delete _staticLibrary;
}
-(void) requestOperation: (NSString*)what withBuffer: (void*)buf size: (int)theSize
{
_staticLibrary->requestOperation( [what UTF8String], buf, theSize );
}
@end
这样的事情。我不知道你的案例中requestOperation的参数究竟是什么,所以我只是做了一个有根据的猜测。
您可以编写自己的lambda并使其成为一种方法,而不是将ObjC块传递给-initWithCallback:
,而不是:
-(instancetype) init
{
__weak JCRStaticLibrary *weakSelf = self; // Avoid retain circle.
_staticLibrary = new staticLibrary( [weakSelf](){ [weakSelf doCallbackThing]; }, "en"); // ObjC++ knows how to turn an ObjC block into a C++ lambda.
}
-(void) doCallbackThing
{
// Do whatever the callback should do here.
}
这实际上取决于每次创建此类型的对象时是否更改回调(例如,如果JCRStaticLibrary对象表示通过网络发送的命令),或者来自一遍又一遍使用的一小组命令(例如,收到一个视频帧并对其应用一个过滤器,然后将其移交给另一个对象,所以你真的只有一个回调)。在前一种情况下,你想保留块,在后者中,每个过滤器都有一个子类可能更有意义(除非你想在过滤器之间切换)。