Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong behaviour of NSArray on arm64 (but works on x86_64) #77

Closed
teticio opened this issue Apr 2, 2021 · 3 comments
Closed

Wrong behaviour of NSArray on arm64 (but works on x86_64) #77

teticio opened this issue Apr 2, 2021 · 3 comments

Comments

@teticio
Copy link

teticio commented Apr 2, 2021

Problem:
The NSArray contains only the first element of the list on the iPhone. The NSArray is correctly set to the full list on the iPhone emulator however.

iPhone 7: iOS 1.14.1
iPhone 8 emulator: iOS 1.14

main.py:

import kivy
from kivy.app import App
from kivy.uix.label import Label
from pyobjus import autoclass, objc_arr

NSArray = autoclass('NSArray')

class MyApp(App):

    def build(self):
        shape = [1, 96, 216, 1]
        array = NSArray.arrayWithObjects_(*shape + [None])
        output_shape = [
            array.objectAtIndex_(_).intValue()
            for _ in range(array.count())
        ]
        return Label(text=f'{output_shape}')


if __name__ == '__main__':
    MyApp().run()

relevant parts of buildozer.spec:

requirements = python3,kivy,pyobjus
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.10.0

Any ideas? I am trying to set the shape of a tensor for TensorFlow Lite and I have tried everything I can think of - even casting to a ctypes pointer to ints. I'd be very grateful for any pointers (no pun intended) or workarounds. Thanks!

@misl6
Copy link
Member

misl6 commented Apr 3, 2021

Hi @teticio

NSArray.arrayWithObjects: is a variadic function, and should be prepared accordingly before calling it via ffi.

(We should use ffi_prep_cif_var instead of ffi_prep_cif over here if the function is variadic):

f_status = ffi_prep_cif(&self.f_cif, FFI_DEFAULT_ABI,

Unfortunately, (AFAIK) We don't have a proper way to distinguish a variadic function by looking at its signature.

Maybe We can add a list of function that We know that are variadic, or let the user to force it as variadic? What do you think about it @tito? Seems reasonable?

Meanwhile, as a workaround, you can easely populate the array by doing something like that:

NSMutableArray = autoclass("NSMutableArray")
NSArray = autoclass("NSArray")

mutarray = NSMutableArray.new()

for x in [1, 96, 216, 1]:
    mutarray.addObject_(x)

array = NSArray.arrayWithArray_(mutarray)
        
output_shape = [
     array.objectAtIndex_(_).intValue()
      for _ in range(array.count())
 ]
        
print(output_shape)

@teticio
Copy link
Author

teticio commented Apr 3, 2021

Thanks for this! Funnily enough, I was just reading through the Pyobjus documentation again and I had the same idea for a workaround and I just came back here to grab my code to try it out. Good to know!

@misl6
Copy link
Member

misl6 commented Mar 26, 2022

Fixed via #85

@misl6 misl6 closed this as completed Mar 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants