On Monday, February 24, 2003, at 12:35 AM, Dan Mills wrote:

$OBJC_EXPORT{'application:openFile:'} = { 'args'=>'@@', 'return'=>'c' };

What do '@@' and 'c' mean? And why is this needed (but not needed for things like 'myApp::openDocument' which is called magically when I press M-o or click on File->Open)?

When ObjC calls a method, it first asks for the "method signature" - basically a string that describes the argument and return types. Unfortunately, Perl doesn't have much in the way of introspection - primarily because subs can accept pretty much whatever parameters you throw at them, and return whatever you ask them for.


So, we have to punt, and provide a method signature to give to ObjC when it asks for one. I didn't want to do this for every single method, though, so I provided for defaults - if there is no 'args' element, the number of colons in the selector is used to find the number of arguments, with each argument declared as an object - '@', and if there is no 'return' element, the default is 'void' - 'v'. If neither is present, or the key for the requested selector is not present in the relevant package's %OBJC_EXPORT hash at all, both defaults are used.

There is also another element you can use - 'method'. If you supply a 'method' element, its value is used instead of a calculated method name. For example, by default, messages received with the ObjC selector "application:openFile:" would be routed to the Perl method application_openFile(). If you supplied a 'method' element with a value of 'openFile', however, they'd be routed to that Perl method instead.

In theory, this could be used to route a number of different ObjC selectors to a single Perl method - in practice, I haven't yet found a need to do that. Nor have I found any real benefit to routing selectors to names that don't correspond to them. But the capability is there, should you need it.

So, what are the type symbols? A complete list can be found in "Object Oriented Programming and the Objective-C Language", under the heading "Type Encoding" pp 119. The most useful ones, though, are:

'c' - char (also BOOL, which is a typedef'd char)
'i' - int
's' - short
'l' - long
'q' - long long
'C' - unsigned char
'I' - unsigned int
'S' - unsigned short
'L' - unsigned long
'Q' - unsigned long long
'f' - float
'd' - double
'v' - void
'*' - character string (char *)
'@' - an object, either statically-typed or id
':' - a selector

Enumerations are passed as ints, and many - but not all - constants as NSString objects.

So, here are a couple of concrete examples:

The NSApplication delegate method declared like this:

- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag

would be declared in Perl like this:

$OBJC_EXPORT{'applicationShouldHandleReopen:hasVisibleWindows:'} = {
        'args' => '@c', 'return' => 'c' };
sub applicationShouldHandleReopen_hasVisibleWindows {
        my ($self, $theApplication, $flag) = @_;
}

The NSBrowser delegate method declared like this:
- (void)browser:(NSBrowser *)sender willDisplayCell:(id)cell atRow:(int)row column:(int)column


Looks like this in Perl:
$OBJC_EXPORT{'browser:willDisplayCell:atRow:column:'} = {
        'args' => '@@ii' };
sub browser_willDisplayCell_atRow_column {
        my ($self, $sender, $cell, $row, $column) = @_;
}

I chose delegate methods for both of the above examples, because in many other cases where a Perl method is called by ObjC, the default signature is adequate. Action methods connected in Interface Builder, for example, and observer methods that are called in response to posted NSNotifications, take a single object argument, and return void - so neither of these types of methods need to have method signatures built for them.

sherm--

Heisenberg may have slept here.



Reply via email to