Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write objective c wrapper for c++ methods?

I need to write a wrapper class in objective c for C++ class.

I have referred the following Can't find standard C++ includes when using C++ class in Cocoa project and was able to get rid of the lexical or Preprocessor issue: 'vector' file not found issue.

However, I do not understand coverting a C++ methods which accept several parameters to objective c method.

Can someone please help me to do so ? What i want to do is to write a wrapper class for this http://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html#a0af91755d71eecfce5781f2cd759db85

I have tried to do so and followings are the method I am stuck with ...

//  Wrapper.h

#import <Foundation/Foundation.h>

@interface Wrapper : NSObject {
    void *myRubberBandStretcher;
}

#pragma mark - Member Functions
-(void)process:(const float)input samples:(size_t)samples final:(bool)final;
@end

/////////////////////////////////////////////////////////////////////////////////

//Wrapper.mm

#import "Wrapper.h"
#import "RubberBandStretcher.h"

@implementation Wrapper


-(id)init {
self = [super init];
if (self) {
   myRubberBandStretcher = new RubberBand::RubberBandStretcher::RubberBandStretcher(44100, 2, 0, 1.0, 1.0);
}
return self;
}

-(void)process:(const float)input samples:(size_t)samples final:(bool)final {
static_cast<RubberBand::RubberBandStretcher *>(myRubberBandStretcher)->process(<#const float *const *input#>, <#size_t samples#>, <#bool final#>)
}
like image 942
Ankahathara Avatar asked Feb 12 '15 06:02

Ankahathara


1 Answers

You should read up on "compilation units". In short, there's no way to tell what language a header file is written in for the compiler. Therefore, it always uses the language of the source file that includes the header. So if you include a C++ header from a .m file, it will not work. For every ObjC file that uses a C++ header, you have to change the file name suffix of the source file that uses it from .m to .mm. You do not need the source files for your rubberband library, you simply need to make all the files that use it ObjC++ instead of just ObjC.

Of course, you may not want to change all your files to be ObjC++. Your code for the alternate approach of wrappering the C++ is pretty close. One thing I noticed is that you still have the <#foo#> placeholders in your code (Xcode may display them as blue rounded cartouches, which is probably why you haven't noticed them before). Replace those with the actual names of the parameter variables, just like you would with a regular C function call, and all should compile. I.e.:

-(void)process:(const float)input samples:(size_t)samples final:(bool)final {
    static_cast<RubberBand::RubberBandStretcher *>(myRubberBandStretcher)->process( input, samples, final );
}

Also note that you seem to have omitted the semicolon after the process call.

BTW, you can also get rid of having to use static_cast everywhere, see the tricks listed here: Can I separate C++ main function and classes from Objective-C and/or C routines at compile and link? and there might also be some more useful info here: How to call C++ method from Objective-C Cocoa Interface using Objective-C++

like image 109
uliwitness Avatar answered Nov 12 '22 17:11

uliwitness