Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling C++ from Objective-C

For those of you who have successfully been able to call C++ code from Objective-C, will you please enlighten me?

This link says you need to wrap your C++ code using a technique he describes in his article. It looks good but I still have problems.

This link says that as long as the Objective-C class calling the C++ class has been converted to a .mm (Objective-C++) class then the two should work nicely together.

Each of these approaches are causing me grief the minute I try to add a method call. Can somebody please give me code for a simple Hello World iOS app that uses Objective-C for the "Hello" part and a C++ class for the "World" part with an Objective-C++ class in the middle? Or do I still have the entire concept wrong?

like image 946
Patricia Avatar asked Oct 07 '13 16:10

Patricia


People also ask

How do you call C from Objective-C?

To call a C function from the Objective-C, you need to create a . h header file to include the C function declaration, and, of cause, include the . h file in the . c source file where the C function resides.

Can I use C in Objective-C?

You really can't use C in Objective-C, since Objective-C is C. The term is usually applied when you write code that uses C structures and calls C functions directly, instead of using Objective-C objects and messages.

Is Objective-C as fast as C?

Objective-C uses the runtime code compilation Generally, this happens very fast but when the code compilation happens a significant number of times, it becomes measurable. Objective-C is a superset of C and all C functions that you will write in Objective-C will be just as fast.

Who invented Objective-C?

Objective-C was created primarily by Brad Cox and Tom Love in the early 1980s at their company Productivity Products International (PPI). Leading up to the creation of their company, both had been introduced to Smalltalk while at ITT Corporation's Programming Technology Center in 1981.


1 Answers

Essentially you need an ObjC class with .mm extension that calls an ObjC class with .mm extension. The second one will be used as a C++ wrapper class. The wrapper class will call your actual .cpp class. It's a little tricky, so I'm going to give you some verbose code. Here is an overview of the project:

enter image description here

In your ObjC code (ViewController) you would call the CplusplusMMClass

- (IBAction)buttonPushed:(UIButton *)sender {
    self.mmclass = [[CplusplusMMClass alloc]init];  // bad practice; but showing code
    NSString *str = [self.mmclass fetchStringFromCplusplus];
    [self populateLabel:str];
}

Here is the CplusplusMMClass .h and .mm

#import <Foundation/Foundation.h>
#import "WrapperClass.h"

@interface CplusplusMMClass : NSObject
@end

@interface CplusplusMMClass()
@property (nonatomic, strong) WrapperClass *wrapper;
- (NSString*)fetchStringFromCplusplus;
@end

#import "CplusplusMMClass.h"
#import "WrapperClass.h"

@implementation CplusplusMMClass

- (NSString*)fetchStringFromCplusplus {
    self.wrapper = [[WrapperClass alloc] init];
    NSString * result = [self.wrapper getHelloString];
    return result;
}

@end

Here is WrapperClass .h and .mm

#ifndef HEADERFILE_H
#define HEADERFILE_H

#import <Foundation/Foundation.h>

#if __cplusplus

#include "PureCplusplusClass.h"

@interface WrapperClass : NSObject
@end

@interface WrapperClass ()
- (NSString *)getHelloString;
@end


#endif
#endif

#import "WrapperClass.h"

#include "WrapperClass.h"
#include "PureCplusplusClass.h"

using namespace test;

@interface WrapperClass ()
@property (nonatomic) HelloTest helloTest;
@end

@implementation WrapperClass

- (NSString *)getHelloString {
    self.helloTest = *(new HelloTest);
    std::string str = self.helloTest.getHelloString();
    NSString* result = [[NSString alloc] initWithUTF8String:str.c_str()];
    return result;
}

@end

Here is the PureCplusplusClass .h and .cpp

#ifndef __HelloWorld__PureCplusplusClass__
#define __HelloWorld__PureCplusplusClass__

#include <stdio.h>
#include <string>

using namespace std;

namespace test {
    class HelloTest
    {
    public:
        std::string getHelloString();
    };
}

#endif /* defined(__HelloWorld__PureCplusplusClass__) */

#include <stdio.h>
#include <string>

std::string test::HelloTest::getHelloString() {
    std::string outString = "Hello World";
    return outString;
}

This code is not perfect! I'm having trouble with the namespace test being recognized. I'll update when I can.

But this should get you there!!!!

like image 59
Patricia Avatar answered Oct 07 '22 21:10

Patricia