views:

39

answers:

1

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.

A: 

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.

Jeff
Thank you very much. That works. :DWhere and why does it get deleted before the call?
Matthew Mitchell
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.
Jeff