Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Mysterious Crash
-
I have a script where I'm trying to get the system attributes; eventually this will gather memory information. I have isolated the crash to this line of code:
from ctypes import POINTER from objc_util import ObjCClass, ObjCInstance, c, c_void_p NSHomeDirectory = c.NSHomeDirectory NSHomeDirectory.restype = c_void_p NSHomeDirectory.argtype = [] NSFileManager = ObjCClass('NSFileManager') LP_c_void_p = POINTER(c_void_p) def get_system_attributes(): file_manager = NSFileManager.defaultManager() error = LP_c_void_p() attributes = file_manager.attributesOfFileSystemForPath_error_( ObjCInstance( NSHomeDirectory() ).cString(), error ) return attributes get_system_attributes()
attributesOfFileSystemForPath_error_
takes a string and an error pointer. It crashes when it gets to the error inside that function. I think it crashes due to anNSError
object being created. Any ideas on how to stop the crash? -
The crash seems to come from your
cString()
call. The method expects anNSString
object, and you already have that, so simply removing.cString()
should fix the crash. -
Btw, if you're not actually interested in the error, you can also just pass
None
for that (you could still detect failure by checking if the return value isNone
; you only need the error pointer if you want details about the failure). -
To add on to what @omz said I also saw a crash with the error variable as well.
Here is my fix:path = ObjCInstance(NSHomeDirectory()) file_manager = NSFileManager.defaultManager() error = c_void_p() a = file_manager.attributesOfFileSystemForPath_error_(path, pointer(error)) print(ObjCInstance(error)) print(a)
The only major change that I made was to use
ctypes.pointer
instead ofctypes.POINTER
as the upper case version is for defining argtypes and restypes or values in structures where as the lower case version is used for creating pointer objects -
@Cethric I think
byref(error)
would be a little faster (at least that's what the ctypes docs say). -
Good catch, I can't say I have done a speed test on iOS to see the differences between the two, but in general yes
byref(error)
is faster thanpointer(error)
-