4

I'm playing around with calling c++ methods from Swift project. I used this tutorial to set and get string value, worked perfectly.

Then I tried to do the same with integer value and I encountered some problems in my objective-c wrapper class.

#import <Foundation/Foundation.h>
#import "TestCppClassWrapper.h"
#include "TestCppClass.h"
@interface TestCppClassWrapper()
@property TestCppClass *cppItem;
@end
@implementation TestCppClassWrapper
- (instancetype)initWithTitle:(NSString*)title: (NSInteger*)variable
{
    if (self = [super init]) {
        self.cppItem = new TestCppClass(std::string([title cStringUsingEncoding:NSUTF8StringEncoding]), std::uintptr_t(variable));
    }
    return self;
}
- (NSString*)getTitle
{
    return [NSString stringWithUTF8String:self.cppItem->getTtile().c_str()];
}
- (void)setTitle:(NSString*)title
{
    self.cppItem->setTitle(std::string([title cStringUsingEncoding:NSUTF8StringEncoding]));
}
- (NSInteger*)getVariable
{
    return [NSInteger self.cppItem->getVariable()];
}
- (void)setVariable:(NSInteger*)variable
{
    self.cppItem->setVariable(std::NSInteger(variable));
}
@end

Problem occurs here, as you may have guessed

enter image description here

I'm not much familiar neither with obj-c nor with c++, that's why I'm unable to figure how how exactly should I deal with types, string is quite individual case(encoding and stuff), so it's hard for me to relate it to Int.

#include "TestCppClass.h"
TestCppClass::TestCppClass() {}
TestCppClass::TestCppClass(const std::string &title, const std::int8_t &variable): m_title(title), m_variable(variable) {}
TestCppClass::~TestCppClass() {}
void TestCppClass::setTitle(const std::string &title)
{
    m_title = title;
}
void TestCppClass::setVariable(const std::int8_t &variable)

{
    m_variable = variable * 2;
}
const std::string &TestCppClass::getTtile()
{
    return m_title;
}
const std::int8_t &TestCppClass::getVariable()
{
    return m_variable;
}

Thanks in advance

theDC
  • 6,364
  • 10
  • 56
  • 98
  • There is indeed no `NSInteger` class in the C++ standard library's namespace. What does `TestCppClass::getVariable` return? – molbdnilo Aug 09 '16 at 13:45
  • see my edited question please :) – theDC Aug 09 '16 at 13:47
  • Short answer is no you can not call C++ directly inside Swift code. You are however able to create an Objective-C wrapper for the C++ code and call that with Swift. Related post: http://stackoverflow.com/questions/24042774/can-i-mix-swift-with-c-like-the-objective-c-mm-files?rq=1 – SierraMike Aug 09 '16 at 15:52

2 Answers2

4

NSInteger is not a class, it's a typedef for long, so just use it as-is.

You could do

- (instancetype)initWithTitle:(NSString*)title: (NSInteger)variable
{
    if (self = [super init]) {
        self.cppItem = new TestCppClass(std::string([title cStringUsingEncoding:NSUTF8StringEncoding]), variable);
    }
    return self;
}

- (NSInteger) getVariable
{
    return self.cppItem->getVariable();
}
- (void)setVariable:(NSInteger)variable
{
    self.cppItem->setVariable(variable);
}

but you'd get a narrowing conversion in the setter.
(I'm not sure if that's an issue or if NSInteger is crucial for your Swift interface.)

And passing around std::int8_t by reference is pointless - just use it "plain".

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • Indeed errors disappeareed but now i got in Swift `let wrapperItem = TestCppClassWrapper(title: "Init test text for cpp item wrapper class", 7)` I get "Cannot convert value of type 'Int' to expected argument type 'UnsafeMutablePointer' – theDC Aug 09 '16 at 13:57
  • @DCDC Added the change you need to make to `initWithTitle` (which is to remove an asterisk). – molbdnilo Aug 09 '16 at 14:01
  • the error remains unfortunately, maybe I should change something with type in cpp file? – theDC Aug 09 '16 at 14:03
  • @DCDC Get rid of the const-reference thing. Don't use `const std::int8_t&`, use `std::int8_t`. – molbdnilo Aug 09 '16 at 14:04
  • same again, type int can't be converted to `'UnsafeMutablePointer'`, also a lot of errors in wrapper come out when const are deleted – theDC Aug 09 '16 at 14:06
  • @DCDC And your C++ has no `const std::int8_t &` left? It's important that you remove the ampersand, `&`. – molbdnilo Aug 09 '16 at 14:17
  • yes I deleted all `const` and `&` still the same error message – theDC Aug 10 '16 at 06:47
1

NSInteger(variable) is an Objective C method, effectively in the global namespace. It is not in the std namespace. Omit the std:: part.

What is the interface of TestCppClass class?

Alexander
  • 59,041
  • 12
  • 98
  • 151