Thursday, August 7, 2008

NSTask

My initial attempts to include a C program file in a Cocoa-Python XCode project haven't worked. However, I do have a working example of using NSTask to run a C program as a separate process. I don't know if there is any advantage to doing it the Cocoa way (as opposed to using subprocess.Popen). The code in the AppDelegate is:

class PyXAppDelegate(NSObject):
def applicationDidFinishLaunching_(self, sender):
NSLog("Application did finish launching.")

argL = ['13', '47', '36']
#p = NSHomeDirectory() + '/Desktop/example'
p = NSBundle.mainBundle().pathForResource_ofType_('example', None)
#print 'path', p

t = NSTask.alloc().init()
t.setLaunchPath_(p)
t.setArguments_(argL)

cent = NSNotificationCenter.defaultCenter()
cent.addObserver_selector_name_object_(
self,
"checkATaskStatus:",
NSTaskDidTerminateNotification,
None)

t.launch()

@objc.signature('v@:@')
def checkATaskStatus_(self, notification):
status = notification.object().terminationStatus()
if status == 0: print 'success'
else: print 'error'

The C file looks (amost) like this:

#include < stdio.h>
#include < stdlib.h>
#include < string.h>
#include < math.h>

int isPrime(int x) {
int i;
float limit = sqrt(x) + 1;
for (i = 2; i < limit; i++) {
if (!(x % i)) return 0;
}
return 1;
}

int main(int argc, char *argv[])
{
printf("number of args = %i \n", argc);
printf ("path %s\n", argv[0]);
int i;
for (i = 1; i < argc; i++) {
printf("arg #%i, ", i);
int x = atoi(argv[i]);
printf("x = %i, ", x);
printf("isPrime = %i\n", isPrime(x));
}
return 0;
}

It's compiled in the usual way

tom-elliotts-mac-mini-2:~ telliott_admin$ gcc example.c -o example

and then can be placed in a convenient directory, or more flexibly, added to the project. Notable, pathForResource_ofType_ will take 'None' for the second argument.

This is what it prints to the Console:

2008-08-07 19:44:05.325 PyX[3207:10b] Application did finish launching.
number of args = 4
path /Users/telliott_admin/Cocoa.PyObjC/PyX/build/Release/PyX.app/Contents/Resources/example
arg #1, x = 13, isPrime = 1
arg #2, x = 47, isPrime = 1
arg #3, x = 36, isPrime = 0
success