2

I'm trying to use an Objective-C class made in Python to do this but Objective-C can't call the method which calls the python function.

Here's the framework code which the Objective-C code:

//
//  scalelib.h
//  Scalelib Cocoa Framework
//
//  Created by Matthew Mitchell on 04/07/2010.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface Game : NSObject {
    id current_pyfunc;
}
-(void) addPyFunc: (id) pyfunc;
-(void) callPyFunc;
@end

//
//  scalelib.m
//  Scalelib Cocoa Framework
//
//  Created by Matthew Mitchell on 04/07/2010.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "Game.h"


@implementation Game
-(void) addPyFunc: (id) pyfunc{
    current_pyfunc = pyfunc;
}
-(void) callPyFunc{
    [current_pyfunc call]; //Segmentation fault. Method doesn't exist for some reason.
}
@end

Here is the python script which loads the framework and tests the use of callbacks with failure.

#!/usr/bin/env python2.3
from objc import *
import os,sys
loadBundle("Scalelib Cocoa Framework",globals(),os.path.dirname(sys.argv[0]) + "/Scalelib Cocoa Framework/build/Release/Scalelib Cocoa Framework.framework/")
class PythonCallback(NSObject):
    def setCallback_withArgs_(self, python_function,args): #Python initialisation of class, add the callback function and arguments
        self.python_function = python_function
        self.args = args
        return self
    def call(self): #Used by Objective-C to call python function
        self.python_function(*self.args)
def create_callback(function,args):
    return PythonCallback.alloc().init().setCallback_withArgs_(function,args)
def square(num):
    print num**2
instance = Game.alloc().init()
callback = create_callback(square,[3])
callback.call()
instance.addPyFunc_(create_callback(square,[5]))
instance.callPyFunc()

I get the output:

9 Segmentation fault

The segmentation fault is because the call method made in python doesn't exist apparently. So how to I make it exist for Objective-C?

Even if the code did work it would be useless but I'm only testing things at the moment. Once I have the callbacks working, I'll be able to make my library for python.

Thank you for any help.

1 Answer 1

2

My guess would be retain counts.

You don't retain the result of create_callback() that you pass into the addPyFunc_

As such, it probably gets garbage collected away before you call it.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much. That works. :D Where and why does it get deleted before the call?
instance.addPyFunc_(create_callback(square,[5])) gets executed like this: . evaluate square (increment its ref count) . evaluate [5] (create temp object, refcount=1) . pass those arguments to create_callback, get an object in return . decrement python retain count for [5] . decrement python retain count for square . pass the result object to addPyFunc . decrement python retain count of object . it is now zero so garbage collect it. Note, its Python garbage collection, not Cocoa.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.