I am working on a C++ library with a Swift backend (the C++ code mainly serves as a bridge to Rust).
I have the following:
char* get_string(void* pBackend) {
Backend* backend = (Backend*) pBackend;
return backend.get_string ???; // or does this need more processing?
}
In turn Rust will call get_string
from the cpp library, but never mutate it.
The question is how to properly handle this from the Swift side, I have lost count of all the numerous pointer swift and cpp types.
in Swift:
struct Backend {
var myString: String? = nil
func getString() -> ??? { // which type to return?
if let s = myString {
return ??? // how to get it?
} else {
"no String"
}
}
}
I know there may be some lifetime concerns, but as soon as Rust call get_string
, it copies the contents.
(The backend has more internal functions that will actually set myString
.)
It is possible to just return a Swift String
on the Swift side. Swift String
s can be easily converted to std::string
s. See also the documentation.
// Make these public so that they can be accessed from C++
public struct Backend {
var myString: String? = nil
public func getString() -> String {
return myString ?? "no String"
}
}
On the C++ side, you can do:
char* get_string(void* pBackend) {
Backend* backend = (Backend*) pBackend;
swift::String stringFromSwift = backend->getString();
std::string cppString = (std::string)stringFromSwift;
return strdup(cppString.c_str());
}
Since the string needs to outlive get_string
, it needs to be copied to the heap. The caller of get_string
is responsible for free
ing this.