CrazySage
(Gleb Igumnov)
1
Hello, I'm trying to call C++ function that returns std::vector< std::optional< std::string > > and return it in Swift as [String?]
As std::optional cannot be directly handled by Swift, I've tried to make proxy function
If I try to make it with following signature:
swift::Array< swift::Optional< swift::String > > ConvertOptList( std::vector< std::optional< std::string > > param);
I'm getting following error:
Constraints not satisfied for class template 'Array' [with T_0_0 = swift::Optionalswift::String]
Because 'swift::isUsableInGenericContext<swift::Optionalswift::String >' evaluated to false
If I try to return std::vector of Swift optional
std::vector< swift::Optional< swift::String > > ConvertOptList( std::vector< std::optional< std::string > > param)
{
std::vector< swift::Optional< swift::String > > res;
for( auto& obj: param )
{
if( obj )
{
auto opt = swift::Optional< swift::String >::some( swift::String( *obj ) );
res.push_back( opt );
}
else
{
auto opt = swift::Optional< swift::String >::none();
res.push_back( opt );
}
}
return res;
}
I'm getting following errors:
Undefined symbols:
Linker command failed with exit code 1 (use -v to see invocation)
Without details on undefined symbols, but problem is with push_back.
Is there a way to correctly convert such data?
P.S. also, if I try to make function that return one optional string
swift::Optional< swift::String > GetOptString( bool fill );
it isn't imported in Swift. Is it bug or also some limitation?
egor.zhdan
(Egor Zhdan)
2
Hi,
Swift/C++ interop supports std::optionals, you should be able to work with std::optionals from Swift.
Could you try to implement the conversion function in Swift?
Something like this:
// .h
typedef std::vector<std::optional<std::string>> MyCxxVector;
// .swift
func convert(_ v: MyCxxVector) -> [String?] {
return v.map { Optional(fromCxx: $0) }
}
CrazySage
(Gleb Igumnov)
3
I'm getting error
Cannot convert value of type 'Optional<std.__1.optional<basic_string<Int8, char_traits, allocator>>.Wrapped>' (aka 'Optional<std.__1.basic_string<Int8, char_traits, allocator>>') to closure result type 'String?'
Also in case of single optional I cannot build String from it
func GetOptString( fill: Bool ) -> String?
{
let res = cxx.GetOptString(fill)
if( res.hasValue )
{
return String( res.value )
}
return nil
}
I'm getting
No exact matches in call to initializer
Oh right, you would also need to convert Optional<...basic_string> to Optional<String>
Please try this conversion function:
func convert(_ v: MyCxxVector) -> [String?] {
return v.map {
if let o = Optional(fromCxx: $0) {
return String(o)
} else {
return nil
}
}
}
CrazySage
(Gleb Igumnov)
5
Yes, it works like that. Thanks