Objective-Everything Release 5. Copyright ©1994-1998 by TipTop Software, Inc. All Rights Reserved.
Objective-Python facilitates direct and seamless interaction with compiled C code and data structures. C symbols live in the ObjPy.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, ObjPy, etc. In addition, any user-specific definitions provided in ~/.AppInfo/ObjectiveEverythin/User.cfun will be automatically loaded at startup as well. See the Resources section for more info. At runtime, you can explicitly load any additional definitions using the cimport command.
NOTE: ObjPy gives you full and unrestricted access to C. Although ObjPy 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 objpy, type import AppKit; AppKit.run(), and then click Objective->Interact->Interactor and select "Python". This is only relevant because some examples below invoke the NSRunAlertPanel() function or operate on the NSApp object which is non-existent or nil if the appkit is not running.
The C Parser subsystem provides the following two commands:
Declare/define C stuff, i.e., types, functions, globals, classes, categories, protocols, etc., using the C/ObjC syntax.
Example
py% 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:
py% cdef(""" %-> extern double sin(double); %-> %-> @protocol MyProtocol %-> - (void)aMethod; %-> @end %-> %-> @interface NSObject(Add_A_Method) %-> - (NSString*)sayHello; %-> /* ObjPy: %-> return "%s sez hello to you" % self %-> */ %-> @end %-> """, out=1) 'sin <"?"d"?"d>\012#@protocol MyProtocol\012#@category NSObject(Add_A_Method)\012' py% C.sin(1) 0.841470984808 py% print unparse(Protocol.MyProtocol) @protocol MyProtocol // Implemented by: no one
// Class methods: none
// Instance methods - (void)aMethod; @end
py% CGlob.NSApp.sayHello()
'<TTApplication: 0x8f728> 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.
Parses C/ObjC syntax text from file.
Example:
py% from ObjPy import *
py% cinclude('/usr/include/ansi/stdio.h',cpp='')
py% f=C.fopen('/tmp/test','w')
py% C.fprintf(f,'Hello World!\n')
0
py% C.fclose(f)
0
In ObjPy, Type object is used to represent C/ObjC types. You use the standard ObjC syntax to specify types.
Creates a type object.
Defines new type tname. This is equivalent to typedef in C.
Returns type encoding.
type.type
Returns type description.
Returns expanded type description.
Returns type size.
Returns type alignment.
Returns prettyfied type description.
Example:
py% Type.NSRect Type.NSRect py% print Type.NSRect.expand struct { struct { float x; float y; } origin; struct { float width; float height; } size; } py% Type.NSRect.size 16 py% Type('union { int x; char *y; float d;}').encoding '("x"i"y"*"d"f)' py% Type('struct mystruct').encoding '{mystruct="anInt"i"aDouble"d"anObject"@"aString"*"anArray"@}' py% print Type('union { int x; char *y; float d;}').pretty union { int x; STR y; float d; }
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.
Similar to malloc, except that the C datum object that is returned "owns" the allocated memory. That is, when the datum is released by Python, malloced memory will be freed.
In ObjPy 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.
Returns the datum object which is registered in the global C symbol table with name
Registers datum into global C symbol table with name. This is equivalent to defining a global symbol (global variable or function) in C.
Clones the datum
Creates a datum with the specified type and address.
Casts datum into type.
Casts method into a function datum.
Casts object into a pointer datum.
Example:
py% C.NSApp.type Type.id py% C.NSApp.val <TTApplication: 0x86098> py% app=C.NSApp.val py% app <TTApplication: 0x86098> # cast object into pointer datum py% C(app).type Type("""struct { Class isa; id _nextResponder; NSEvent* _currentEvent; ... }""") py% C(app).addr 549016 py% C(app).val (Class.TTApplication, nil, <NSEvent: 0x99790>, ...) # cast a method into a function datum py% a=Class.NSArray() py% o=Class.NSObject() py% fun=C(o.description) py% fun.type Type("id description(id self, SEL _cmd)") py% a.description() '()' py% fun(a,'description') '<NSConcreteArray: 0x3c7f8>' # cast a function py% pf=C(Type('void ()(char *format, double d, int i, STR x)'),'printf') py% pf('d=%g, i=%d, x=%s\n', 123.45, 678, 'hi') # (the output appears in the shell/console window)
Returns datum's type.
Returns datum's memory address.
Returns datum's type encoding.
Returns datum's size.
A pointer datum object represents a value stored in memory. There are two types of pointer data:
You create a datum by allocating memory to hold item(s) of a certain type.
Reallocates pointer datum to hold cnt items of whatever the datum's type is.
Deallocates memory that the pointer points to.
Offsets the datum.
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:
If the datum is a pointer array datum, then the index must be an integer in range [0:len(ptr)]
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 py% p=Type.NSRect.malloc() py% p.val=((1,2),(3,4)) py% p.val ((1.0, 2.0), (3.0, 4.0)) py% p.fetch('origin') (1.0, 2.0) py% p.fetch('size.width') 3.0 py% p.fetch(['size','height']) 4.0 py% p.fetch('1.0') 3.0 # Reallocate p to be a pointer array datum of length 2 py% p.realloc(2) <CDatum: ^{?="origin"{?="x"f"y"f}"size"{?="width"f"height"f}}@0xd4138[2]> py% p[1]=((5,6),(7,8)) py% p.val (((1.0, 2.0), (3.0, 4.0)), ((5.0, 6.0), (7.0, 8.0))) # Free p py% p.free() <CDatum: ^{?="origin"{?="x"f"y"f}"size"{?="width"f"height"f}}@0x0[2]> # allocate 5 NSPoints; q "owns" the malloced memory py% q=Type('NSPoint[5]')() py% print q.type.expand struct { float x; float y; } [5] # Store/fetch index py% q.store(123,'2.x') <CDatum*: ^[5{?="x"f"y"f}]@0xd4138> py% q.val ((0.0, 0.0), (0.0, 0.0), (123.0, 0.0), (0.0, 0.0), (0.0, 0.0)) # & operator returns the item address py% q.fetch('&') <CDatum: ^[5{?="x"f"y"f}]@0xd4138> py% q <CDatum*: ^[5{?="x"f"y"f}]@0xd4138> # Get the address of q[2].y: q2y=&(q[2].y); py% q2y=q.fetch('2.y.&') py% q2y.val=456 py% q.val ((0.0, 0.0), (0.0, 0.0), (123.0, 456.0), (0.0, 0.0), (0.0, 0.0)) # This will free memory, since q "owns" it py% del q py% app=C.NSApplication.sharedApplication() # Fetch all instance variables of an object at once py% C(app).val (Class.TTApplication, nil, <NSEvent: 0x1b6924>, ...) # Get a pointer to an instance variable py% currentEventPtr=C(app).fetch('_currentEvent.&') py% currentEventPtr.type Type("NSEvent*") py% currentEventPtr-C(app) 2 # Get the value pointed to py% currentEventPtr.val <NSEvent: 0x1b6e44> py% print currentEventPtr.val NSEvent: type=KeyDown loc=(0,0) time=...
Returns a pointer datum which is i items offset from ptr. i must be an integer.
Pointer difference.
Pointer array data behaves like a Python sequence.
Pointer array length.
Dereferences (fetches) value at index idx.
Stores value at index idx.
Returns a pointer datum corresponding to the slice.
Copies stuff at ptr2 into the pointer array slice. This is the bcopy operation.
Stores values in sequence valseq into corresponding elements of the slice.
Bzero's element values in the slice.
Example:
py% p=Type.int(10) py% len(p) 10 py% p[5]=555 py% p[2:3]=(123,) py% p[3:5]=[20,21] py% p.val (0, 0, 123, 20, 21, 555, 0, 0, 0, 0) py% q=p[3:3] py% len(q) 0 py% q.val 20 py% p[7:10]=p[2:5] py% p.val (0, 0, 123, 20, 21, 555, 0, 123, 20, 21)
You can use CGlob as a convenience for accessing C global variables.
Same as: C.name.val
Same as: C.name.val=v
C function datum is used to invoke a C function.
Invoke a function with arguments.
Example:
py% C.cos(1) 0.540302305868 py% C.NSRunAlertPanel('ObjPy', 'Hello World!', nil, nil, nil) 1