matteoh
matteoh

Reputation: 3590

How to pass and return an object to a C++ function called from iOS Swift?

In my iOS project, I want to call a C++ function from my Swift code that takes an object from my Swift code and returns another object.

So far, following this tutorial and adding a little bit more stuff, I managed to call a C++ function that takes a simple parameter and returns a string:

#import <Foundation/Foundation.h>

@interface NativeLibWrapper : NSObject

- (NSString *) sayHello: (bool) boolTest;

@end

#import <Foundation/Foundation.h>

#import "NativeLibWrapper.h"
#import "NativeLib.hpp"

@implementation NativeLibWrapper

- (NSString *) sayHello: (bool) boolTest {
    NativeLib nativeLib;
    std::string retour = nativeLib.sayHello(boolTest);
    return [NSString stringWithCString: retour.c_str() encoding: NSUTF8StringEncoding];
}

@end

#ifndef NativeLib_hpp
#define NativeLib_hpp

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

class NativeLib
{
public:
    std::string sayHello(bool boolTest);
};

#endif /* NativeLib_hpp */

#include "NativeLib.hpp"

std::string NativeLib::sayHello(bool boolTest)
{
    return "Hello C++ : " + std::to_string(boolTest);
}
#import "NativeLibWrapper.h"
NativeLibWrapper().sayHello(true)

But now, let's say that my C++ sayHello() function takes this kind of object as a parameter (so I can access it in the C++ function):

class TestAPOJO {

    var value1 = ""
    var value2 = false
}

and returns this kind of object (generated from the C++ function but then mapped into a Swift object, or something like that):

class TestBPOJO {

    var value3 = 0.0
    var value4 = false
}

How can I achieve that?

Thanks.

Upvotes: 1

Views: 722

Answers (1)

matteoh
matteoh

Reputation: 3590

OK so here is what I did to make it work:

  • create Objective-C TestAPOJO and TestBPOJO classes:
// TestAPOJO.h:

#import <Foundation/Foundation.h>

@interface TestAPOJO : NSObject

@property NSString *value1;
@property bool value2;

@end


// TestAPOJO.mm:

#import "TestAPOJO"

@implementation TestAPOJO

@end
  • create C++ TestAPOJOFromC and TestBPOJOFromC classes:
// TestAPOJOFromC.hpp:

#ifndef TestAPOJOFromC_hpp
#define TestAPOJOFromC_hpp

class TestAPOJOFromC
{
public:
    TestAPOJOFromC();
    ~TestAPOJOFromC();
    
    std::string value1;
    bool value2;
};

#endif /* TestAPOJOFromC_hpp */


// TestBPOJOFromC.cpp:

#include "TestBPOJOFromC.hpp"

TestBPOJOFromC::TestBPOJOFromC()
{
    value1 = "";
    value2 = false;
}

TestBPOJOFromC::~TestBPOJOFromC() = default;

  • in the NativeLibWrapper.h file, add:

- (TestBPOJO *) getTestPOJOS: (TestAPOJO *) testAPOJO;

  • in the NativeLibWrapper.mm file, add:
- (TestBPOJO *) getTestPOJOS: (TestAPOJO *) testAPOJO {
    NativeLib nativeLib;
    TestAPOJOFromC *testAPOJOFromC = new TestAPOJOFromC();
    testAPOJOFromC->value1 = std::string([testAPOJO.value1 UTF8String]);
    testAPOJOFromC->value2 = testAPOJO.value2;
    TestBPOJOFromC * testBPOJOFromC = nativeLib.getTestPOJOS(testAPOJOFromC);

    TestBPOJO *testBPOJO = [TestBPOJO new];
    testBPOJO.value3 = testBPOJOFromC->value3;
    testBPOJO.value4 = testBPOJOFromC->value4;
    return testBPOJO;
}

Upvotes: 1

Related Questions