c++iosobjective-cobjective-c++

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?


Solution

  • 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!!!!