Closed 0rvar closed 2 years ago
I never considered that Swift allowed nil values 😅
Adding a null check is one way to handle it, but I think it'd be better to allow using Rust's Option type.
I've done some testing and it seems that thanks to null-pointer optimisation, this can be done quite easily! Just gotta make SRObject contain a NonNull pointer and use #[repr(transparent)]
rather than #[repr(C)]
. Works with SRObject and SRArray.
@Brendonovich I am not quite sure what you mean.
In my case, the swift function is defined kind of like this:
@_cdecl("get_foo")
public func getFoo() -> Foo? {}
So, the returned object itself is nullable. How would I then type the linked function in Rust?
I tried this:
#[link(name = "myfoolib")]
extern "C" {
fn get_foo() -> SRObject<Option<FooObjc>>;
}
But this causes a segfault when I dereference the SRObject and nil was returned from swift
I managed to get this working, but only once I created this type manually:
#[repr(C)]
#[derive(Debug)]
enum NullablePtr<T> {
Null,
NonNull(T),
}
Then I could define the linked function like this:
#[link(name = "myfoolib")]
extern "C" {
fn get_foo() -> NullablePtr<SRObject<FooObjc>>;
}
@0rvar The solution I outlined was to do with the internals of SRObject, in your case all that would be required is giving get_foo
the signature () -> Option<SRObject<FooObjc>>
. The NonNull pointer will be held internally by SRObject, and will allow Rust to ensure that the Option works properly. I haven't pushed any changes yet but will soon so that you can try it out
Option<SRObject<T>>
works perfectly with latest master! Thank you
How do I handle nil returned from a swift function? The
*const
pointer inSRObject
is private, so I can't checkresult.0.is_null()
. Any other option?EDIT: Opened a PR: #5