K
Kevin Walzer
I'm trying to implement a Perl interface to a subset of Apple's
AppleEvent framework, allowing a Perl app to respond to AppleScript
commands. CPAN has a module devoted to this, but it is part of a larger
framework that is suffering from bit-rot, has large swaths of deprecated
and obsolete API calls, and won't build under 64-bit.
I'm moving right along with the AppleEvent / C API stuff, but I'm not
quite clear on how to convert this vanilla C code into something that
Perl can interface with. What I want to do is to pass a subroutine name
as a string to the Perl interpreter that the interpreter can run.
Here's one example C function:
//Handler for AppleEvents
static OSErr AEScriptsAEHandler(const AppleEvent *theAppleEvent,
AppleEvent *reply, long refCon) {
OSErr err = noErr;
AEDesc returnData;
AEEventID eventID;
OSType typeCode;
AEDesc directParameter;
char *script;
//Read the AppleEvent
err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeUnicodeText,
&returnData);
//get event ID to look up in CFDictionary
err = AEGetAttributePtr(theAppleEvent, keyEventIDAttr, typeType,
NULL, &eventID, sizeof(eventID), NULL );
//get direct parameter
err = AEGetKeyDesc(theAppleEvent, keyDirectObject, typeType,
&directParameter);
CFStringRef scriptName;
stringeventID = UTCreateStringForOSType(eventID);
scriptName = CFDictionaryGetValue(aeDict, stringeventID);
CFIndex length = CFStringGetLength(scriptName);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length,
kCFStringEncodingUTF8);
script = (char *)malloc(maxSize);
CFStringGetCString(scriptName, script, maxSize, kCFStringEncodingUTF8);
//actually run the script
err = ExecuteScript(script, NULL);
}
What this code does is check a CFDictionary ref for a value that
corresponds to the ID of a specific Apple event ("script"), and my idea
is to pass the "script" string to a function called "ExecuteScript" that
would incorporate the Perl interpreter. Is there a simpler way to
implement this than wading through all the XSUB goo?
In Tcl's C API it's simple as initializing a Tcl interpreter:
static Tcl_Interp *myInterp;
and then calling this function:
Tcl_Eval(myInterp, script);
In looking at the XS bits, am I missing something simpler that might
serve my needs? The idea here is that I'm passing a single subroutine
call to the Perl interpreter, then I'll be returning the subroutine's
output back to the AppleEvent C API as a string. There aren't a lot of
hooks or complex data structures that need to be addressed: I just want
to have this as a loadable module that can interact with the running
interpreter.
Thanks for any advice,
Kevin
AppleEvent framework, allowing a Perl app to respond to AppleScript
commands. CPAN has a module devoted to this, but it is part of a larger
framework that is suffering from bit-rot, has large swaths of deprecated
and obsolete API calls, and won't build under 64-bit.
I'm moving right along with the AppleEvent / C API stuff, but I'm not
quite clear on how to convert this vanilla C code into something that
Perl can interface with. What I want to do is to pass a subroutine name
as a string to the Perl interpreter that the interpreter can run.
Here's one example C function:
//Handler for AppleEvents
static OSErr AEScriptsAEHandler(const AppleEvent *theAppleEvent,
AppleEvent *reply, long refCon) {
OSErr err = noErr;
AEDesc returnData;
AEEventID eventID;
OSType typeCode;
AEDesc directParameter;
char *script;
//Read the AppleEvent
err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeUnicodeText,
&returnData);
//get event ID to look up in CFDictionary
err = AEGetAttributePtr(theAppleEvent, keyEventIDAttr, typeType,
NULL, &eventID, sizeof(eventID), NULL );
//get direct parameter
err = AEGetKeyDesc(theAppleEvent, keyDirectObject, typeType,
&directParameter);
CFStringRef scriptName;
stringeventID = UTCreateStringForOSType(eventID);
scriptName = CFDictionaryGetValue(aeDict, stringeventID);
CFIndex length = CFStringGetLength(scriptName);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length,
kCFStringEncodingUTF8);
script = (char *)malloc(maxSize);
CFStringGetCString(scriptName, script, maxSize, kCFStringEncodingUTF8);
//actually run the script
err = ExecuteScript(script, NULL);
}
What this code does is check a CFDictionary ref for a value that
corresponds to the ID of a specific Apple event ("script"), and my idea
is to pass the "script" string to a function called "ExecuteScript" that
would incorporate the Perl interpreter. Is there a simpler way to
implement this than wading through all the XSUB goo?
In Tcl's C API it's simple as initializing a Tcl interpreter:
static Tcl_Interp *myInterp;
and then calling this function:
Tcl_Eval(myInterp, script);
In looking at the XS bits, am I missing something simpler that might
serve my needs? The idea here is that I'm passing a single subroutine
call to the Perl interpreter, then I'll be returning the subroutine's
output back to the AppleEvent C API as a string. There aren't a lot of
hooks or complex data structures that need to be addressed: I just want
to have this as a loadable module that can interact with the running
interpreter.
Thanks for any advice,
Kevin