Passing string between Swift and C++

I want to understand what the recommended way is for string interoperability between swift and c++. Below are the 3 ways to achieve it. Approach 2 is not allowed at work due to restrictions with using std libraries.

Approach 1:

In C++:

char arr[] = "C++ String";
void * cppstring = arr;
std::cout<<"before:"<<(char*)cppstring<<std::endl;           // C++ String
// calling swift function and passing the void buffer to it, so that swift can update the buffer content
Module1::SwiftClass:: ReceiveString (cppstring, length);  
std::cout<<"after:"<<(char*)cppstring<<std::endl;             // SwiftStr     

In Swift:

func ReceiveString (pBuffer : UnsafeMutableRawPointer , pSize : UInt ) -> Void
{
  // to convert cpp-str to swift-str:
  let swiftStr = String (cString: pBuffer.assumingMemoryBound(to: Int8.self));
  print("pBuffer content: \(bufferAsString)");

  // to modify cpp-str without converting:
   let swiftstr:String = "SwiftStr"     
      _ =  swiftstr.withCString { (cString: UnsafePointer<Int8>) in
        pBuffer.initializeMemory(as: Int8.self, from: cString, count: swiftstr.count+1)
    }
} 

Approach 2:  The ‘String’ type returned from a swift function is received as ‘swift::String’ type in cpp. This is implicitly casted to std::string type. The std::string has the method available to convert it to char *.

void 
TWCppClass::StringConversion ()
{
    // GetSwiftString() is a swift call that returns swift::String which can be received in std::string type
    std::string stdstr = Module1::SwiftClass::GetSwiftString ();
    char * cstr = stdstr.data ();
    const char * conststr= stdstr.c_str ();
}

  

Approach 3:

The swift::String type that is obtained from a swift function can be received in char * by directly casting the address of the swift::String. We cannot directly receive a swift::String into a char *.

void 
TWCppClass::StringConversion ()
{
   // GetSwiftString() is a swift call that returns swift::String
   swift::String swiftstr = Module1::SwiftClass::GetSwiftString (); 
  // obtaining the address of swift string and casting it into char *
   char * cstr = (char*)&swiftstr;
}

It’s hard to recommend an approach without first understanding the rules as to what you think of as ‘best’. Speaking personally, I value reliability and safety, so I tend to use high-level abstractions where possible.

In the case of C++ / Swift interoperability, that means using the automatic bridging between Swift’s String and C++’s std::string. Which you’ve outlined in approach 2, but it seem that you’re not allowed to use that:

Approach 2 is not allowed at work due to restrictions with using std libraries.

Given that, it seems that you’re not actually asking about bridging between C++ strings and Swift but between C strings and Swift, right?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Passing string between Swift and C&#43;&#43;
 
 
Q