ValueError: depythonifying 'pointer', got 'array.array'

Issue #237 new
Andy Tan
created an issue

Hello,

I have an Objective C initializer initMyClass from MyClass that I’d like to use from Python with the following signature: - (instancetype)initMyClass:(SInt16 )dataArray descriptor:(MyDescriptor )descriptor;

However I get a “depythonifying ‘pointer’” error when I try to use it:

myclass = MyClass.alloc().initMyClass_descriptor_(array.array("l", [1,2,3]), my_descriptor) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: depythonifying 'pointer', got 'array.array'

I check it’s signature and metadata() and all seems well:

MyClass.initMyClass_descriptor_.signature '@32@0:8^s16^{MTImageDescriptor=qdssIiiiSB}24'

MyClass.MyMethod_descriptor_.metadata() {'classmethod': False, 'hidden': False, 'retval': {'_template': True, 'type': '@'}, 'arguments': ({'_template': True, 'type': '@'}, {'_template': True, 'type': ':'}, {'null_accepted': True, 'type': '^s'}, {'null_accepted': True, 'type': '^{MTImageDescriptor=qdssIiiiSB}'})}

In any case I also tried running objc.loadBundleFunctions() but it couldn’t find my function:

objc.loadBundleFunctions(my_bundle, globals(), [("MyClass.initMyClass_descriptor_", "^l^@")], skip_undefined=False) Traceback (most recent call last): File "<stdin>", line 1, in <module> objc.error: cannot find a function

Any suggestions on how I should proceed? Thanks.

Comments (1)

  1. Ronald Oussoren repo owner

    To start with the easiest part: objc.loadBundleFunctions is used to load global functions (like NSApplicationMain), not methods (or selectors as they are known in Objective-C).

    For the arguments you'll have to do some more work because PyObjC doesn't know what to do with pointers.

    r = objc.registerMetaDataForSelector
    r('MyClass', b'initMyClass:descriptor:', { 'arguments': { 2: { 'type_modifier': 'n', 'c_array_of_variable_size': True }})
    

    This says that your first argument is used to pass data to the method, and that it is an C array of some unknown length. If you're just passing a single value you can leave out the "c_array..." bit. Use "o" instead of "n" for output arguments.

    This is described at https://pyobjc.readthedocs.io/en/latest/metadata/manual.html, but I don't know how readable that documentation is if you don't already know how this works (feedback on how to improve that documentation is appreciated)

  2. Log in to comment