objc2
objc2 copied to clipboard
Receiving objective-c pointers through FFI with safe wrappers
I've been looking at the docs for this and objc but haven't really found a good answer to how you'd use this library when bridging objective-c code into Rust. For example, given a objective-C function like
void write(const NSArray<const String *> *fields);
what would be the preferred way to implement this as a extern "C"
function on Rust and wrap the parameter with appropriate Foundation types? I've been getting by so far by using *const Object
and raw msg_send!, but it would be nice to understand how I can use the existing type definitions.
Hmm, would be easier to answer if I knew the exact function, can you point me to the documentation for a concrete example? And what is String
in this context, did you mean NSString
?
In any case, const NSArray<NSString>*
can be represented in Rust as *const objc2::foundation::NSArray<objc2::foundation::NSString>
, maybe that helps a bit?
Yeah it's supposed to be NSString.
I dug into it a bit more and figured out where I was going wrong: I had tried your suggestion with NSArray<Object>
to iterate on the types, but Object
does not impl INSObject
, so the NSArray<Object> type ended up being pretty useless. After specifying NSArray<NSString> this works out for me.
Here's an example of what I was doing for posterity's sake:
#[no_mangle]
pub unsafe extern "C" fn write(ptr: *const NSArray<Object>) {
let count: usize = msg_send![ptr, count];
for i in 0 .. count {
let value: *const Object = msg_send![ptr, objectAtIndex: i];
// do something with field.
}
}
If I want to use a custom type (one not implemented in objc2::foundation) do I have to define my own class? Or is there a way to say NSArray<any INSObject>
?
If you have a place where docs around this belongs I'm happy to write something down to make this easier for the next person trying to do this
Object
does not implINSObject
Sounds like you're using an older version of the library? INSObject
doesn't exist any more, and the stuff you're talking about should be possible with Object
now?
an example of what I was doing
So could be simplified to (while keeping the same ABI):
#[no_mangle]
pub unsafe extern "C" fn write(fields: Option<&NSArray<NSString>>) {
fields.map(|fields| fields.unwrap().iter().map(|obj| {
// Do something with `obj`
}))
}
If I want to use a custom type (one not implemented in objc2::foundation) do I have to define my own class? Or is there a way to say
NSArray<any INSObject>
?
If it's in a generic context, you can do NSArray<T> where T: Message
.
If not, you can just do NSArray<Object>
.
Note that you can define a type that can be used as an interface to a class with the new extern_class!
macro.
Got it, yeah I was using the latest stable version per docs.rs (0.2.7 for objc2, 0.1.1 for objc2-foundation) but seems like I'll be better off using the alpha versions that have built on what objc provides.
Thanks for taking the time here, appreciate the help!
Yeah, will get a stable release out fairly soon, but you know, to actually promise stability I need to be sure it's at a point where I'd want to keep backwards compatibility (for a while at least).
So, a stable release is still a ways away, since I decided to make icrate
(and that will take a lot longer to stabilize).
But I'll close this issue for now, at least