2

I am trying to pass two Strings from Swift to the C++ function, handle them there, and then return an array of integers (probally a vector), not sure yet.

I've tried it with (C++ function declaration):

void exmaple(char* one, char* two);

But was not able to pass the strings from Swift to C++.

Then I changed the function a little:

void example(void* one, void* two)
{
    string &a = *reinterpret_cast<string*>(one);
    string &b = *reinterpret_cast<string*>(two);

    cout<<"String b is: "<<b<<endl;
}

and tried calling the function in Swift:

let aStr = UnsafeMutablePointer<String>.alloc(10)
aStr.initialize("stringA")

let bStr = UnsafeMutablePointer<String>.alloc(10)
bStr.initialize("stringB")

example(aStr, bStr)

But the only output I get is:

String b is: 

How can I pass two Strings from Swift to a C++ function, and then return an array/vector of integers?

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Dejan Skledar
  • 11,280
  • 7
  • 44
  • 70

1 Answers1

2

Swift has some magic bridging that allows you to pass regular Swift strings directly into C functions. For example, strlen has the signature size_t strlen(const char *), which comes into Swift as func strlen(_: UnsafePointer<Int8>) -> UInt but you can call it with ordinary strings like this:

import Darwin

let greeting: String = "Hello!"

strlen(greeting)   // returns 6

strlen("Goodbye")  // returns 7

And the compiler will automatically generate null-terminated C strings for the call.

The last part of your question is much trickier unfortunately. Not only is there actually no bridging to C++, only C and Objective-C, there most definitely won't be the ability to pass back a C++ vector. Your best bet is either to go via an Objective-C layer and pass back an NSArray, or to use C-style pass in an empty buffer and have the function write the values into it.

Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
  • Okay, but how do I pass the Strings to the C++ function? I declared the function with const char* parameter, but cant get it working on the Swift side: let bStr = UnsafeMutablePointer.alloc(1) bStr.initialize("example") exampleFunc(bStr) -> "Cannot invoke example with arguments..." – Dejan Skledar Apr 09 '15 at 18:42
  • No need for unsafe mutable anything. Just pass in the String. Look at my example, `strlen` takes a `const char *` but I am passing in a `String` as an argument. – Airspeed Velocity Apr 09 '15 at 18:50
  • Just passing the String or NSString didnt work, I got it working with converting the NSString to a cString, and passing it! Now I just need to return an array of Integers or vector of Integers.. The hard part, as you said.. – Dejan Skledar Apr 09 '15 at 18:51
  • You shouldn't need to convert it to an NSString. Just pass the String straight in. For an example of how a C function can receive an array from Swift and populate it, take a look at how `sysctlbyname` (which takes a buffer and populates it) is being called in this example: http://stackoverflow.com/a/25467259/3925941 – Airspeed Velocity Apr 09 '15 at 18:55
  • You are right. Works the same with just the String. Any Idea for the return though? I get problems in the extern "C" with the vector type.. Or how could I pass back a NSArray? – Dejan Skledar Apr 09 '15 at 18:57
  • Look at that link in my prev comment. You can create an array and pass that in to be received in C as a pointer to a buffer (with a length argument) to be populated. – Airspeed Velocity Apr 09 '15 at 18:59