For reasons unknown these files were never checked in to CVS.

This commit is contained in:
Jack Jansen 1999-03-17 21:44:07 +00:00
parent 8368453249
commit cd219d5efd
3 changed files with 213 additions and 0 deletions

57
Mac/Demo/calldll/readme Normal file
View File

@ -0,0 +1,57 @@
Preliminary notes/documentation for the calldll module, version 0.2.
====================================================================
Calldll allows you to call random C functions from python without writing any
C code. It is mainly meant to call MacOS toolbox routines for which no Python
wrapper module is available. It is also incomplete, in that only a few argument
types are currently supported. Please let me know which other argument types
you need, and/or whether you have any ideas on a general "escape" allowing people
to pass anything.
The module works *only* on PowerPC currently. It is distributed complete
with source and project files, so that people willing to look at a CFM68K port
are welcome to do so. A classic 68K implementation is impossible, I think (so
prove me wrong, please:-).
The module exports three functions:
- symtable = getlibrary(libraryname)
Get a reference to import library libraryname. "InterfaceLib" is the most commonly
used one, containing most toolbox routines. The symbol table can be used
to lookup routines to be passed to newcall: "symtable.WaitNextEvent" will
return the address of routine WaitNextEvent. and so will "symtable['WaitNextEvent']".
The symtable is a mapping, so you can use keys() and len(...) to inspect it.
- symtable = getdiskfragment(file)
Load the specified file (given by fsspec or filename) and return a reference to
its symboltable.
- callable = newcall(routine, returntype, [argtype, ...])
Return a callable object. You specify the C routine to be called (as explained above),
the type of the return value and the argument types. The resulting object can
be called from Python code in the normal way, and typechecking on arguments is
performed (but, of course, if you specify incorrect argument types in this call
you may well crash your machine). Printing a callable will give you a description
of the (C-) calling sequence.
The C return value can be one of 'None', 'Byte', 'Short', 'Long', 'Pstring' (a pascal
string returned by address, copied to a Python string), 'Cobject' (a wrapper around a void
pointer), 'Handle' (a new handle, returned as a Res.Resource object) or 'OSErr' (which raises
MacOS.Error if non-zero).
Arguments can be any of 'InByte', 'InShort', 'InLong', 'InString' (a python string, with the
address of the data passed to the C routine, so be careful!), 'InPstring' (a python string copied
to a Str255 and passed by address), 'InCobject', 'InHandle', 'OutByte' (storage is allocated for
a single byte, the address passed to C and the resulting value returned to Python), 'OutShort',
'OutLong', 'OutPstring' (again: storage pre-allocated and the address passed to C), 'OutCobject'
(storage for a void * is allocated, this void ** is passed to C and the resulting void * is
encapsulated in the Cobject returned) or 'OutHandle' (ditto, which means that this is usually *not*
what you use, you normally use 'InHandle' because most toolbox calls expect you to preallocate
the handle).
All values to be returned (from the return value and the Out arguments) are collected. If there
aren't any None is returned, if there is one value this value is returned, if there are multiple
values a tuple is returned.
There is test code in testcalldll.py, and a minimal example in samplecalldll.py.
Have fun, and let's discuss the design of this thingy on pythonmac-sig,
Jack Jansen, jack@cwi.nl, 23-May-97.

View File

@ -0,0 +1,24 @@
#
# Test calldll. Tell the user how often menus flash, and let her change it.
#
import calldll
import sys
# Obtain a reference to the library with the toolbox calls
interfacelib = calldll.getlibrary('InterfaceLib')
# Get the routines we need (see LowMem.h for details)
LMGetMenuFlash = calldll.newcall(interfacelib.LMGetMenuFlash, 'Short')
LMSetMenuFlash = calldll.newcall(interfacelib.LMSetMenuFlash, 'None', 'InShort')
print "Menus currently flash",LMGetMenuFlash(),"times."
print "How often would you like them to flash?",
# Note: we use input(), so you can try passing non-integer objects
newflash = input()
LMSetMenuFlash(newflash)
print "Okay, menus now flash", LMGetMenuFlash(),"times."
sys.exit(1) # So the window stays on-screen

View File

@ -0,0 +1,132 @@
import calldll
import macfs
import sys
import MacOS
import Res
fss, ok = macfs.PromptGetFile("Show me calldll.ppc.slb")
lib = calldll.getdiskfragment(fss, 'calldll.ppc.slb')
cdll_b_bbbbbbbb = calldll.newcall(lib.cdll_b_bbbbbbbb, 'Byte', 'InByte', 'InByte',
'InByte', 'InByte','InByte', 'InByte','InByte', 'InByte')
cdll_h_hhhhhhhh = calldll.newcall(lib.cdll_h_hhhhhhhh, 'Short', 'InShort', 'InShort',
'InShort', 'InShort','InShort', 'InShort','InShort', 'InShort')
cdll_l_llllllll = calldll.newcall(lib.cdll_l_llllllll, 'Long', 'InLong', 'InLong',
'InLong', 'InLong','InLong', 'InLong','InLong', 'InLong')
cdll_N_ssssssss = calldll.newcall(lib.cdll_N_ssssssss, 'None', 'InString', 'InString',
'InString', 'InString', 'InString', 'InString', 'InString', 'InString')
cdll_o_l = calldll.newcall(lib.cdll_o_l, 'OSErr', 'InLong')
cdll_N_pp = calldll.newcall(lib.cdll_N_pp, 'None', 'InPstring', 'OutPstring')
cdll_N_bb = calldll.newcall(lib.cdll_N_bb, 'None', 'InByte', 'OutByte')
cdll_N_hh = calldll.newcall(lib.cdll_N_hh, 'None', 'InShort', 'OutShort')
cdll_N_ll = calldll.newcall(lib.cdll_N_ll, 'None', 'InLong', 'OutLong')
cdll_N_sH = calldll.newcall(lib.cdll_N_sH, 'None', 'InString', 'InHandle')
print 'Test cdll_b_bbbbbbbb'
rv = cdll_b_bbbbbbbb(1, 2, 3, 4, 5, 6, 7, 8)
if rv == 36:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_b_bbbbbbbb negative'
rv = cdll_b_bbbbbbbb(-1, -2, -3, -4, -5, -6, -7, -8)
if rv == -36:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_h_hhhhhhhh'
rv = cdll_h_hhhhhhhh(1, 2, 3, 4, 5, 6, 7, 8)
if rv == 36:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_h_hhhhhhhh negative'
rv = cdll_h_hhhhhhhh(-1, -2, -3, -4, -5, -6, -7, -8)
if rv == -36:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_l_llllllll'
rv = cdll_l_llllllll(1, 2, 3, 4, 5, 6, 7, 8)
if rv == 36:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_l_llllllll negative'
rv = cdll_l_llllllll(-1, -2, -3, -4, -5, -6, -7, -8)
if rv == -36:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_N_ssssssss'
print 'Should print one two three four five six seven eight'
rv = cdll_N_ssssssss('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight')
if rv == None:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_o_l(0)'
rv = cdll_o_l(0)
if rv == None:
print 'ok.'
else:
print 'Error, returned', rv
print 'Test cdll_o_l(-100)'
try:
rv = cdll_o_l(-100)
print 'Error, did not raise exception, returned', rv
except MacOS.Error, arg:
if arg[0] == -100:
print 'ok.'
else:
print 'Error, returned incorrect exception arg:', arg[0]
print 'Test cdll_N_pp'
rv = cdll_N_pp('pascal string')
if rv == 'Was: pascal string':
print 'ok.'
else:
print 'Failed, returned', `rv`
print 'Test cdll_N_bb'
rv = cdll_N_bb(-100)
if rv == -100:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_N_hh'
rv = cdll_N_hh(-100)
if rv == -100:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_N_ll'
rv = cdll_N_ll(-100)
if rv == -100:
print 'ok.'
else:
print 'Failed, returned', rv
print 'Test cdll_N_sH'
h = Res.Resource('xyz')
rv = cdll_N_sH('new data', h)
if rv == None and h.data == 'new data':
print 'ok.'
else:
print 'Failed, rv is', rv, 'and handle data is', `rv.data`
sys.exit(1)