TransWikia.com

objective-c call python method with multiple parameters use py2app and pyobjc

Stack Overflow Asked by ChenLin Wang on December 5, 2021

I’m testing on macOS at 10.15.6 and I hope obJC can call Python. But I’ve had a few problems so far:

I can introduce OBJC in Python using PyobJC and use Py2App to package Python programs as ".plugin" plug-in.

None of this was a problem, but the Cocoa application crashed when one of python’s multi-parameter methods was called from OBJC

Here’s my code:

python programs:

setup.py

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['CLPYTry.py']
DATA_FILES = []
OPTIONS = {}

setup(
    plugin=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

CLPYTry.py

import objc
from Cocoa import NSObject

class CLPYTry(NSObject):
    def init(self):
        self = super(CLPYTry, self).init()
        return self

    # @objc.signature('@@:@')
    def doSomeThing_(self, aString):
        return aString + " Handled!"

    # @objc.signature('i@:i:i')
    def doSomeThing2_int2_(self, aInt, aInt2):
        return aInt + 100 + aInt2

There is also this Objc template code for CLPYTry:

CLTry.h:

//
//  SympyTry.h
//  ObjcPy_Draw
//

#ifndef SympyTry_h
#define SympyTry_h

#import <Foundation/Foundation.h>

@interface CLTry : NSObject

- (NSString *)doSomeThing:(NSString *)string;

- (int)doSomeThing2:(int)integer int2:(int)aint2;

@end

#endif /* SympyTry_h */

I’m executed this objc program:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    
    NSBundle * pluginBundle =  [NSBundle bundleWithPath:@"/Users/XXX/Desktop/ObjcPy_Draw/ObjcPy_Draw/Python_Plugin/dist/CLPYTry.plugin"];

    Class pyClass = [pluginBundle classNamed:@"CLPYTry"];
    CLTry * py = [[pyClass alloc] init];
    NSLog(@"%@", [py doSomeThing:@"a string"]);
    NSLog(@"%d", [py doSomeThing2:10 int2:10]);
}

When I execute the "NSLog(@"%d", [py doSomeThing2:10 int2:10]);" line, the cocoa program crashes and throws the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0xa)"
console output:

2020-07-23 11:42:55.054028+0800 ObjcPy_Draw[6214:181410] a string Handled!

Obviously, such a direct call is not possible. So,how can objc call the multiparameter method of python?

Any help will be accepted with gratitude.

One Answer

Unless you do something special the Objective-C declaration for you Python class should be:

@interface CLTry : NSObject

- (NSString *)doSomeThing:(NSString *)string;

- (NSObject*)doSomeThing2:(NSObject*)integer int2:(NSObject*)aint2;

@end

That is, the method with 2 arguments should use Cocoa classes instead of plain C types in its signature. It is possible to declare the Python method with a different signature by explicitly creating objc.selector instances.

Answered by Ronald Oussoren on December 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP