Objective-Everything Release 5.  Copyright ©1994-1998 by TipTop Software, Inc.  All Rights Reserved.

   Integration with C

Objective-Perl facilitates direct and seamless interaction with compiled C code and data structures.  C symbols live in the C namespace.

The Objective-Everything system maintains global tables of type names and symbol names.  When the system starts up, it loads these tables from the module directories of each module that is loaded: Mod.framework/Resources/Mod.cfun, where, Mod is ObjCore, ObjAppKit, ObjTcl, ObjPerl, etc.  In addition, any user-specific definitions provided in ~/.AppInfo/ObjectiveEverythin/User.cfun will be automatically loaded at startup as well.  At runtime, you can explicitly load any additional definitions.

NOTE: ObjPerl gives you full and unrestricted access to C.  Although ObjPerl by default does check for invalid memory access and such, just like in C, be careful not to crash the system.

All of the examples below are executed in an AppKit interactor.  To run an AppKit interactor, simply double-click on ObjShell.app.  Alternatively, run objperlsh, type use AppKit; AppKit::run(), and then click Objective->Interact->Interactor and select "Perl".  This is only relevant because some examples below operate on the NSApp object which is non-existent or nil if the appkit is not running, or invoke the NSRunAlertPanel() function.

C Parser

The C Parser subsystem provides the following two commands:

cdef(stuff [,kwflags])

Declare/define C stuff, i.e., types, functions, globals, classes, categories, protocols, etc., using the C/ObjC syntax.

Keyword flags:
out
integer 0/1
no_def
integer 0/1

Example:

 perl% cdef ' 
 %--->    struct mystruct { 
 %--->      int anInt; 
 %--->      double aDouble; 
 %--->      id anObject; 
 %--->      char *aString; 
 %--->      NSArray *anArray; 
 %--->    }; 
 %--->    typedef struct mystruct *xyz; 
 %--->    double cos(double); 
 %--->    extern int errno; 
 %---> '; 

This registers "struct mystruct" and type "xyz" in the global C type table.  It also registers function "cos" and global "errno" with the specified prototypes in the global symbol table.

Example:

 perl% cdef ' 
 %--->   extern double sin(double); 
 %---> 
%--->   @protocol MyProtocol %--->   - (void)aMethod; %--->   @end %---> %--->   @interface NSObject(Add_A_Method) %--->   - (NSString*)sayHello; %--->   /* ObjPerl: %--->      return "$_[0] sez hello to you" %--->   */ %--->   @end %---> ', { "out" => 1 }; 'sin <"?"d"?"d> #@protocol MyProtocol #@category NSObject(Add_A_Method) ' perl% C::sin(1); 0.841470984807897 perl% print unparse(protocol 'MyProtocol'); @protocol MyProtocol // Implemented by: no one
 // Class methods: none 
 // Instance methods 
 - (void)aMethod; 
 @end 
 perl% $NSApp->sayHello(); 
 <NSInlineCString:0x.*> 
 perl% "" . $NSApp->sayHello(); 
 '<TTApplication:0x...> sez hello to you' 

Note: The cdef facility is not a full-fledged C compiler: C function bodies, and ObjC method bodies are not parsed.

Note: Mixing multiple-language method implementations in a single category definition is not yet fully supported.

cinclude(stuff [,kwflags])

Parses C/ObjC syntax text from file.

Example:

 perl% cinclude '/usr/include/ansi/stdio.h', {"cpp" => ''}; 
 '' 
 perl% $f=C::fopen('/tmp/test','w'); 
 ^{_iobuf}@0x50c248c 
 perl% C::fprintf($f,"Hello World\n"); 
 0 
 perl% C::fclose($f); 
 0 

Type System

In ObjPerl, Type object is used to represent C/ObjC types.  You use the standard ObjC syntax to specify types.

new Type 'name'

Creates a type object.

$type->define('tname')

Defines new type tname.  This is equivalent to typedef in C.

Attributes

$type->encoding

Returns type encoding.

$type->name

Returns type description.

$type->expand

Returns expanded type description.

$type->size

Returns type size.

$type->align

Returns type alignment.

$type->pretty

Returns prettyfied type description.

Example:

 perl% $t=new Type 'NSRect'; 
 NSRect 
 perl% $t->expand; 
 'struct { 
 struct { 
 float x; 
 float y; 
 } origin; 
 struct { 
 float width; 
 float height; 
 } size; 
 }' 
 perl% $t->size; 
 16 
 perl% (new Type 'union { int x; char *y; float d;}')->encoding; 
 '("x"i"y"*"d"f)' 
 perl% (new Type 'struct mystruct')->encoding; 
 '{mystruct="anInt"i"aDouble"d"anObject"@"aString"*"anArray"@}' 
 perl% (new Type 'union { int x; char *y; float d;}')->pretty; 
 'union { 
 int x; 
 STR y; 
 float d; 
 }' 

Methods

$type->malloc([cnt])

Allocates memory for cnt items of the specified type.  A C pointer array datum of length cnt is returned.
If cnt is not specified, memory for one item is allocated, and a regular C pointer datum is returned.

C Data

In ObjPerl C data is represented by the C datum objects.  Every C datum has two properties: type and address.  There are two C datum subtypes: pointer datum and function datum.

new C 'name'

Returns the datum object which is registered in the global C symbol table with name.

new C type, address
new Ctype, 'symbol'

Creates a datum with the specified type and address.

new C type, datum

Casts datum into type.

new C object, selector

Casts method into a function datum.

new C object

Casts object into a pointer datum.

Example:

 perl% $NSApp_datum=new C 'NSApp'; 
 NSApp 
 perl% $NSApp_datum->typeof; 
 id 
 perl% $app=$NSApp_datum->FETCH; 
 <TTApplication:0x15158c> 
 # cast object into pointer datum 
 perl% (new C $app)->typeof; 
 struct { 
 Class isa; 
 id _nextResponder; 
 NSEvent* _currentEvent; 
 ... 
 } 
 perl% (new C $app)->addrof; 
 ... 
 perl% (new C $app)->FETCH; 
 [TTApplication, nil, <NSEvent:0x...>, ...] 
 # cast a method into a function datum 
 perl% $o=NSObject->object; 
 <NSObject:0x1ecd6c> 
 perl% $a=NSArray->array; 
 <NSConcreteArray:0xb6104> 
 perl% $fun=new C $o, 'description'; 
 <"description"@"self"@"_cmd":>@0x18066440 
 perl% $fun->typeof; 
 id description(id self, SEL _cmd) 
 perl% "". $a->description(); 
 '()' 
 perl% "". $fun->call($a,'description'); 
 '<NSConcreteArray: 0xb6104>' 
 # cast a function 
 perl% $pf=new C 'void ()(char *format, double d, int i, STR x)', 'printf'; 
 <"?"v"format"*"d"d"i"i"x"*>@printf 
 perl% $pf->call("d=%g, i=%d, x=%s\n", 123.45, 678, 'hi'); 
 # (the output appears in the shell/console window) 

Datum Attributes

$datum->typeof

Returns datum's type.

$datum->addrof

Returns datum's memory address.

$datum->size

Returns datum's size.

Pointer Datum

A pointer datum object represents a value stored in memory.   There are two types of pointer data:

Allocation, deallocation, offset

You create a datum by allocating memory to hold item(s) of a certain type.

$ptr->realloc([cnt])

Reallocates pointer datum to hold cnt items of whatever the datum's type is.

$ptr->free()

Deallocates memory that the pointer points to.

$ptr->offset(idx)

Offsets the datum.

Value access

$ptr->FETCH([idx])

Fetches (dereferences) the value pointed to by ptr.  Index idx can be used to specify subdatum.

If the datum is a simple 1-item datum, then the index is a list specifying a path to a subdatum.

Each element of the list can be:
&
the datum itself
*
dereferences the pointer datum.
name
accesses element name of the structure or union datum.  name must be a valid element name for the structure/union.
i
where i is an integer.
pointer datum
dereferences the datum at the offset.
array datum
accesses the i-th array element.
structure/union datum:
accesses i-th struct/union element.

If the datum is a pointer array datum, then the index must be an integer in range [0:len(ptr)].

$ptr->STORE(v[, idx])

Stores value v into the specified (sub)datum.

Example:

 # Allocate a NSRect, store a value in it, read some values 
 # p is a simple 1-element datum 
 perl% $p=(new Type 'NSRect')->malloc; 
 ^{?="origin"{?="x"f"y"f}"size"{?="width"f"height"f}}@0x14c10c 
 perl% $p->STORE([[1,2],[3,4]]); 
 perl% $p->FETCH; 
 [[1, 2], [3, 4]] 
 perl% $p->FETCH('origin'); 
 [1, 2] 
 perl% $p->FETCH('size', 'width'); 
 3 
 perl% $p->FETCH(1,1); 
 4 
 # Reallocate p to be a pointer array datum of length 2 
 perl% $p->realloc(2); 
 perl% $p->STORE([[5,6],[7,8]],1); 
 perl% $p->FETCH(1); 
 [[5, 6], [7, 8]] 
 perl% $p->FETCH(0); 
 [[1, 2], [3, 4]] 
 # Free p 
 perl% $p->free; 
 # allocate 5 NSPoints; q "owns" the malloced memory 
 perl% $q=(new Type 'NSPoint[5]')->malloc; 
 ^[5{?="x"f"y"f}]@0x14c10c 
 perl% $q->typeof->expand; 
 'struct { 
 float x; 
 float y; 
 } [5]' 
 # Store/fetch index 
 perl% $q->STORE(123,2,'x'); 
 perl% $q->FETCH(2); 
 [123, 0] 
 # & operator returns the item address 
 perl% $q->FETCH('&'); 
 ^[5{?="x"f"y"f}]@0x14c10c 
 perl% $q; 
 ^[5{?="x"f"y"f}]@0x14c10c 
 # Get the address of q[2].y:  q2y=&(q[2].y); 
 perl% $q2y=$q->FETCH(2,'y','&'); 
 ^f@0x14c120 
 perl% $q2y->STORE(456); 
 perl% $q->FETCH(2); 
 [123, 456] 
 # This will free memory, since q "owns" it 
 perl% $q->free;
 perl% $app=NSApplication->sharedApplication; 
 # Fetch all instance variables of an object at once 
 perl% (new C $app)->FETCH; 
 [TTApplication, nil, <NSEvent:0x...>, ...] 
 # Get a pointer to an instance variable 
 perl% $currentEventPtr=(new C $app)->FETCH('_currentEvent','&'); 
 ^@'NSEvent'@0x151594 
 perl% $currentEventPtr->typeof; 
 NSEvent* 
 # Get the value pointed to 
 perl% "" . $currentEventPtr->FETCH->description; 
 'NSEvent: type=KeyDown loc=(0,0) time=...' 

C Function Datum

C function datum is used to invoke a C function.

$fun->call(args...)

Invoke a function with arguments.

Note:

C::name(args...)

is short for:

(new C 'name')->call(args...)

Example:

 perl% (new C 'cos')->call(1); 
 0.54030230586814 
 perl% C::cos(1); 
 0.54030230586814 
 perl% C::NSRunAlertPanel('ObjPerl', 'Hello World!', nil, nil, nil); 
 1 

[previous][contents][next]