Thread: [Pyobjc-dev] FahrenheitToCelsiusTransformer
Brought to you by:
ronaldoussoren
From: ufiedler <ufi...@we...> - 2005-02-03 19:21:13
|
Hi, Now I am trying to convert the FahrenheitToCelsiusTransformer example from Apple at file:///Developer/ADC%20Reference%20Library/documentation/Cocoa/ Conceptual/ValueTransformers/index.html. The cocoa version I implemented works as expected. But the python version does not. The registration of the transformer works fine. But allowsReverseTransformation is the only method being called from FahrenheitToCelsiusTransformer? I am using pyobjc 1.2. Thanks u.fiedler class FahrenheitToCelsiusTransformer(NSValueTransformer): def transformedValueClass(self): f=1.2 print "transformedValueClass", f.__class__ return f.__class__ transformedValueClass = accessor(transformedValueClass) def allowsReverseTransformation(self): print "allowsReverseTransformation" return NO def transformedValue(self, value): print "transformedValue", value if value == None: return None fahrenheitInputValue = value # calculate Celsius value celsiusOutputValue = (5.0/9.0)*(fahrenheitInputValue - 32.0) print "transformedValue", value, celsiusOutputValue return celsiusOutputValue def reverseTransformedValue(self, value): print "reverseTransformedValue", value if value == None: return None celsiusInputValue = value # calculate Fahrenheit value fahrenheitOutputValue = ((9.0/5.0) * celsiusInputValue) + 32.0 return fahrenheitOutputValue NibClassBuilder.extractClasses("MainMenu") class TransformerAppDelegate(NibClassBuilder.AutoBaseClass): celsius = ivar('celsius', 'd') def initialize(self): print "initialize" # Registering the Fahrenheit to Celsius value transformer trans = FahrenheitToCelsiusTransformer.alloc().init() NSValueTransformer.setValueTransformer_forName_(trans, u"FahrenheitToCelsiusTransformer") # some tests print " valueTransformerNames", NSValueTransformer.valueTransformerNames() print " valueTransformerForName_", NSValueTransformer.valueTransformerForName_(u"FahrenheitToCelsiusTransfo rmer") print " trans", trans print " type trans", type(trans) print " trans.", ; trans.transformedValueClass() print " trans.", ; trans.transformedValue(4) |
From: Bob I. <bo...@re...> - 2005-02-03 19:45:13
|
On Feb 3, 2005, at 14:22, ufiedler wrote: > Now I am trying to convert the FahrenheitToCelsiusTransformer example > from Apple > at > file:///Developer/ADC%20Reference%20Library/documentation/Cocoa/ > Conceptual/ValueTransformers/index.html. > > The cocoa version I implemented works as expected. But the python > version does not. > > The registration of the transformer works fine. But > allowsReverseTransformation is the > only method being called from FahrenheitToCelsiusTransformer? > > I am using pyobjc 1.2. > > > class FahrenheitToCelsiusTransformer(NSValueTransformer): > def transformedValueClass(self): > f=1.2 > print "transformedValueClass", f.__class__ > return f.__class__ > transformedValueClass = accessor(transformedValueClass) Three things wrong here: (a) it's asking for an Objective-C class. float is not an Objective-C class. Return NSNumber instead. (b) This is a class method.. you should say def transformedValueClass(cls): and declare it as a classmethod(...). PyObjC will make it a class method if there is no -transformedValueClass, because it knows that NSValueTransformer's method signatures and +transformedValueClass is there... but it's better to say it explicitly so it's not easily confused with an instance method. (c) Since it is a classmethod, using accessor will do exactly the wrong thing. Even if this were an instance method, you never need to use accessor(...) for getters. In PyObjC 1.3 you don't need to do it for a setter either, because it scans the bytecode and sees that you are never explicitly returning a value. > > def allowsReverseTransformation(self): > print "allowsReverseTransformation" > return NO As above, this is a class method, so you should declare it as such and call the argument "cls" instead of "self" to avoid confusion. > def transformedValue(self, value): > print "transformedValue", value > if value == None: return None > fahrenheitInputValue = value > # calculate Celsius value > celsiusOutputValue = (5.0/9.0)*(fahrenheitInputValue - 32.0) > print "transformedValue", value, celsiusOutputValue > return celsiusOutputValue > > def reverseTransformedValue(self, value): > print "reverseTransformedValue", value > if value == None: return None > celsiusInputValue = value > # calculate Fahrenheit value > fahrenheitOutputValue = ((9.0/5.0) * celsiusInputValue) + 32.0 > return fahrenheitOutputValue The names of these two functions are wrong. Needs to be 'transformedValue_' and 'reverseTransformedValue_' because the selectors are 'transformedValue:' and 'reverseTransformedValue:'. > NibClassBuilder.extractClasses("MainMenu") > class TransformerAppDelegate(NibClassBuilder.AutoBaseClass): > celsius = ivar('celsius', 'd') > > def initialize(self): > print "initialize" > # Registering the Fahrenheit to Celsius value transformer > trans = FahrenheitToCelsiusTransformer.alloc().init() > NSValueTransformer.setValueTransformer_forName_(trans, > u"FahrenheitToCelsiusTransformer") > > # some tests > print " valueTransformerNames", > NSValueTransformer.valueTransformerNames() > print " valueTransformerForName_", > NSValueTransformer.valueTransformerForName_(u"FahrenheitToCelsiusTransf > ormer") > print " trans", trans > print " type trans", type(trans) > print " trans.", ; trans.transformedValueClass() > print " trans.", ; trans.transformedValue(4) As said in a previous mail, using initialize() if never really useful since you have module-level code in Python. Also, since initialize is a class method, you shouldn't call the argument self and you should explicitly declare it as such so it's not confusing. -bob |
From: ufiedler <ufi...@we...> - 2005-02-03 21:01:08
|
Thank a lot!!! Now it works. >> I am using pyobjc 1.2. > > I would highly recommend using PyObjC top-of-tree. It is very stable > and there has been a lot of work related to KVC/KVO. Yes, thanks for that recommendation. I was unsure whether that is the right thing to do for me. And Bob pointed me to the appropriate subversion client at: http://www.codingmonkeys.de/mbo/ >> class FahrenheitToCelsiusTransformer(NSValueTransformer): >> def transformedValueClass(self): >> f=1.2 >> print "transformedValueClass", f.__class__ >> return f.__class__ >> transformedValueClass = accessor(transformedValueClass) > > Three things wrong here: > (a) it's asking for an Objective-C class. float is not an Objective-C > class. Return NSNumber instead. > (b) This is a class method.. you should say def > transformedValueClass(cls): and declare it as a classmethod(...). > PyObjC will make it a class method if there is no > -transformedValueClass, because it knows that NSValueTransformer's > method signatures and +transformedValueClass is there... but it's > better to say it explicitly so it's not easily confused with an > instance method. > (c) Since it is a classmethod, using accessor will do exactly the > wrong thing. Even if this were an instance method, you never need to > use accessor(...) for getters. In PyObjC 1.3 you don't need to do it > for a setter either, because it scans the bytecode and sees that you > are never explicitly returning a value. (b+c) if I do def transformedValueClass(cls): print "transformedValueClass", NSNumber return NSNumber transformedValueClass = classmethod(transformedValueClass) I get the message: AttributeError: 'FahrenheitToCelsiusTransformer' object has no attribute 'transformedValueClass' but if I do it the wrong way: def transformedValueClass(cls): print "transformedValueClass", NSNumber return NSNumber transformedValueClass = accessor(transformedValueClass) it works fine!? (You don't need to answer this. I will switch to version 1.3a0 now) >> def reverseTransformedValue(self, value): >> print "reverseTransformedValue", value >> if value == None: return None >> celsiusInputValue = value >> # calculate Fahrenheit value >> fahrenheitOutputValue = ((9.0/5.0) * celsiusInputValue) + 32.0 >> return fahrenheitOutputValue > > The names of these two functions are wrong. Needs to be > 'transformedValue_' and 'reverseTransformedValue_' because the > selectors are 'transformedValue:' and 'reverseTransformedValue:'. Oh yes, I have to apologize for that. I should have learned the lesson before. Sorry for being so blind! Thank you a 1000 times Your support is really great u.fiedler It follows the complete and working version for pyobjc 1.2: # # TransformerAppDelegate.py # Transformer # # Value Transformer Example Application # Based on Apples FahrenheitToCelsiusTransformer Example # file:///Developer/ADC%20Reference%20Library/documentation/Cocoa/ Conceptual/ValueTransformers/index.html from Foundation import * from AppKit import * from PyObjCTools import NibClassBuilder from objc import * class FahrenheitToCelsiusTransformer(NSValueTransformer): def transformedValueClass(cls): print "transformedValueClass", NSNumber return NSNumber # transformedValueClass = classmethod(transformedValueClass) transformedValueClass = accessor(transformedValueClass) # this should be wrong def allowsReverseTransformation(cls): print "allowsReverseTransformation" return YES allowsReverseTransformation = classmethod(allowsReverseTransformation) def transformedValue_(self, value): print "transformedValue_", value, type(value) if value == None: return None fahrenheitInputValue = value # calculate Celsius value celsiusOutputValue = (5.0/9.0)*(fahrenheitInputValue - 32.0) print "transformedValue_", value, celsiusOutputValue return celsiusOutputValue def reverseTransformedValue_(self, value): print ">> reverseTransformedValue", value, type(value) if value == None: return None celsiusInputValue = float(value) # calculate Fahrenheit value fahrenheitOutputValue = ((9.0/5.0) * celsiusInputValue) + 32.0 return fahrenheitOutputValue NibClassBuilder.extractClasses("MainMenu") class TransformerAppDelegate(NibClassBuilder.AutoBaseClass): celsius = ivar('celsius', 'd') trans = FahrenheitToCelsiusTransformer.alloc().init() NSValueTransformer.setValueTransformer_forName_(trans, u"FahrenheitToCelsiusTransformer") |
From: Bob I. <bo...@re...> - 2005-02-03 21:30:52
|
On Feb 3, 2005, at 16:02, ufiedler wrote: >>> class FahrenheitToCelsiusTransformer(NSValueTransformer): >>> def transformedValueClass(self): >>> f=1.2 >>> print "transformedValueClass", f.__class__ >>> return f.__class__ >>> transformedValueClass = accessor(transformedValueClass) >> >> Three things wrong here: >> (a) it's asking for an Objective-C class. float is not an >> Objective-C class. Return NSNumber instead. >> (b) This is a class method.. you should say def >> transformedValueClass(cls): and declare it as a classmethod(...). >> PyObjC will make it a class method if there is no >> -transformedValueClass, because it knows that NSValueTransformer's >> method signatures and +transformedValueClass is there... but it's >> better to say it explicitly so it's not easily confused with an >> instance method. >> (c) Since it is a classmethod, using accessor will do exactly the >> wrong thing. Even if this were an instance method, you never need to >> use accessor(...) for getters. In PyObjC 1.3 you don't need to do it >> for a setter either, because it scans the bytecode and sees that you >> are never explicitly returning a value. > > (b+c) if I do > > def transformedValueClass(cls): > print "transformedValueClass", NSNumber > return NSNumber > transformedValueClass = classmethod(transformedValueClass) > > I get the message: > > AttributeError: 'FahrenheitToCelsiusTransformer' object has no > attribute 'transformedValueClass' > > but if I do it the wrong way: > > def transformedValueClass(cls): > print "transformedValueClass", NSNumber > return NSNumber > transformedValueClass = accessor(transformedValueClass) > > it works fine!? (You don't need to answer this. I will switch to > version 1.3a0 now) This was a bug in your test code; the right way is still the right way and it should work the same in 1.2 and 1.3a0. The following code was not correct, specifically: > print " trans.", ; trans.transformedValueClass() This should be type(trans).transformedValueClass() or FahrenheitToCelsiusTransformer.transformedValueClass() Oh, and you should change your Xcode settings so that spaces are used instead of tabs. Most people use 4-space indentation when writing Python because that is the standard for the standard library. -bob |
From: Naveen Michaud-A. <inf...@ya...> - 2005-02-04 18:42:52
|
Hello, I am trying to port the following tutorial over to pyobjc: http://cocoadevcentral.com/articles/000028.php, but I am having trouble mapping some CoreGraphics variables. Here's what I have so far (adapted from wmEnable.py and test_bundleVariables.py): import objc from Foundation import NSBundle p = objc.pathForFramework(u'/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework') bndl = objc.loadBundle("CoreGraphics", global(), bundle_path=p) d = {} objc.loadBundleVariables(bndl, d, [(u'kCGErrorSuccess', objc._C_??), (u'CGDirectDisplayID', objc._C_??)] I am having trouble figuring out the appropriate signatures for these variables/contants. For example, CGDirectDisplayID is defined as typedef struct _CGDirectDisplayID * CGDirectDisplayID; in /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h; but I can't find the struct definition of _CGDirectDisplayID. Since it seems to be used only as an opaque reference, what would it's objective c typecode be? Also, kCGErrorSuccess is defined as 0 in an enum called _CGError in /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGError.h? Is the typecode for this objc._C_UINT? Thanks. __________________________________ Do you Yahoo!? Meet the all-new My Yahoo! - Try it today! http://my.yahoo.com |
From: Bob I. <bo...@re...> - 2005-02-04 19:55:28
|
On Feb 4, 2005, at 1:42 PM, Naveen Michaud-Agrawal wrote: > I am trying to port the following tutorial over to > pyobjc: > http://cocoadevcentral.com/articles/000028.php, but I > am having trouble mapping some CoreGraphics variables. > > Here's what I have so far (adapted from wmEnable.py > and test_bundleVariables.py): > > import objc > from Foundation import NSBundle > p = > objc.pathForFramework(u'/System/Library/Frameworks/ > ApplicationServices.framework/Frameworks/CoreGraphics.framework') > bndl = objc.loadBundle("CoreGraphics", global(), > bundle_path=p) > d = {} > objc.loadBundleVariables(bndl, d, > [(u'kCGErrorSuccess', objc._C_??), > (u'CGDirectDisplayID', objc._C_??)] > > I am having trouble figuring out the appropriate > signatures for these variables/contants. For example, > CGDirectDisplayID is defined as typedef struct > _CGDirectDisplayID * CGDirectDisplayID; in > /System/Library/Frameworks/ApplicationServices.framework/Frameworks/ > CoreGraphics.framework/Headers/CGDirectDisplay.h; > but I can't find the struct definition of > _CGDirectDisplayID. Since it seems to be used only as > an opaque reference, what would it's objective c > typecode be? Also, kCGErrorSuccess is defined as 0 in > an enum called _CGError in > /System/Library/Frameworks/ApplicationServices.framework/Frameworks/ > CoreGraphics.framework/Headers/CGError.h? > Is the typecode for this objc._C_UINT? Thanks. you can use objc._C_INT if you're sure it's pointer sized.. -bob |
From: Naveen Michaud-A. <inf...@ya...> - 2005-02-22 22:40:28
|
Thanks for your help earlier. I ported example worked fine. Now I am trying to call some CoreGraphics functions that return extra information by passing by reference. The problem is that I can't figure out the call signature for loadBundleFunctions, and also the appropriate way to call the function in python. Is there a byref function ala ctypes? As an example, say I have a function (in C): OSErr CGDisplayAddressForWindow( CGDirectDisplayID display, CGDisplayCoord *x, CGDisplayCoord *y, ); where all the variables are typedefined as integers. Would the signature be 'ni^i^ioi'. How would I call it from python? By the way this link is really helpful for the objc typecodes: http://wws.mathematik.hu-berlin.de/pool/gnu/objc-features_1.html#SEC4 --- Bob Ippolito <bo...@re...> wrote: > > On Feb 4, 2005, at 1:42 PM, Naveen Michaud-Agrawal > wrote: > > > I am trying to port the following tutorial over to > > pyobjc: > > http://cocoadevcentral.com/articles/000028.php, > but I > > am having trouble mapping some CoreGraphics > variables. > > > > Here's what I have so far (adapted from > wmEnable.py > > and test_bundleVariables.py): > > > > import objc > > from Foundation import NSBundle > > p = > > > objc.pathForFramework(u'/System/Library/Frameworks/ > > > ApplicationServices.framework/Frameworks/CoreGraphics.framework') > > bndl = objc.loadBundle("CoreGraphics", global(), > > bundle_path=p) > > d = {} > > objc.loadBundleVariables(bndl, d, > > [(u'kCGErrorSuccess', objc._C_??), > > (u'CGDirectDisplayID', objc._C_??)] > > > > I am having trouble figuring out the appropriate > > signatures for these variables/contants. For > example, > > CGDirectDisplayID is defined as typedef struct > > _CGDirectDisplayID * CGDirectDisplayID; in > > > /System/Library/Frameworks/ApplicationServices.framework/Frameworks/ > > > CoreGraphics.framework/Headers/CGDirectDisplay.h; > > but I can't find the struct definition of > > _CGDirectDisplayID. Since it seems to be used only > as > > an opaque reference, what would it's objective c > > typecode be? Also, kCGErrorSuccess is defined as 0 > in > > an enum called _CGError in > > > /System/Library/Frameworks/ApplicationServices.framework/Frameworks/ > > > CoreGraphics.framework/Headers/CGError.h? > > Is the typecode for this objc._C_UINT? Thanks. > > you can use objc._C_INT if you're sure it's pointer > sized.. > > -bob > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IntelliVIEW -- > Interactive Reporting > Tool for open source databases. Create drag-&-drop > reports. Save time > by over 75%! Publish reports on the web. Export to > DOC, XLS, RTF, etc. > Download a FREE copy at > http://www.intelliview.com/go/osdn_nl > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev > __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com |
From: Bob I. <bo...@re...> - 2005-02-22 22:48:12
|
On Feb 22, 2005, at 17:40, Naveen Michaud-Agrawal wrote: > > Thanks for your help earlier. I ported example worked > fine. > > Now I am trying to call some CoreGraphics functions > that return extra information by passing by reference. > The problem is that I can't figure out the call > signature for loadBundleFunctions, and also the > appropriate way to call the function in python. Is > there a byref function ala ctypes? No there isn't. ctypes works perfectly fine on OS X, so you could use it. > As an example, say I have a function (in C): > > OSErr CGDisplayAddressForWindow( > CGDirectDisplayID display, > CGDisplayCoord *x, > CGDisplayCoord *y, > ); > > where all the variables are typedefined as integers. > > Would the signature be 'ni^i^ioi'. How would I call it > from python? Uh.. I have no idea where you came up with that signature, but no it's not correct. From just the part of the header you cut and pasted, I have no way of telling whether the arguments are supposed to be in or in/out, so I don't know what the correct signature would be. > By the way this link is really helpful for the objc > typecodes: > http://wws.mathematik.hu-berlin.de/pool/gnu/objc-features_1.html#SEC4 That documentation is for GNUStep's Objective-C runtime, and isn't quite accurate. The PyObjC documentation links to equivalent documentation at developer.apple.com. I use a script that I wrote that invokes GCC to tell me what the signatures are: % ./osig.py OSErr CGDirectDisplayID CGDisplayCoord\* CGDisplayCoord\* s ^{_CGDirectDisplayID=} ^i ^i #!/usr/bin/env python import sys, os, tempfile, shutil TEMPLATE = """ #include <stdio.h> #include <Carbon/Carbon.h> #include <AppKit/AppKit.h> #include <CoreFoundation/CoreFoundation.h> #include <Foundation/Foundation.h> #include <ApplicationServices/ApplicationServices.h> int main(int argc, char **argv) { %s return 0; } """ CC = '/usr/bin/cc' lines = [] for arg in sys.argv[1:]: lines.append('printf("%%s\\n", @encode(%s));' % (arg,)) tempdir = tempfile.mkdtemp() fnbase = os.path.join(tempdir, 'makeTypeCodes') file(fnbase+'.m', 'w').write(TEMPLATE % ('\n'.join(lines),)) if not os.spawnv(os.P_WAIT, CC, [CC, '-o', fnbase, fnbase+'.m']): for line in os.popen(fnbase): print line.strip() shutil.rmtree(tempdir, ignore_errors=True) > --- Bob Ippolito <bo...@re...> wrote: > >> >> On Feb 4, 2005, at 1:42 PM, Naveen Michaud-Agrawal >> wrote: >> >>> I am trying to port the following tutorial over to >>> pyobjc: >>> http://cocoadevcentral.com/articles/000028.php, >> but I >>> am having trouble mapping some CoreGraphics >> variables. >>> >>> Here's what I have so far (adapted from >> wmEnable.py >>> and test_bundleVariables.py): >>> >>> import objc >>> from Foundation import NSBundle >>> p = >>> >> objc.pathForFramework(u'/System/Library/Frameworks/ >>> >> > ApplicationServices.framework/Frameworks/CoreGraphics.framework') >>> bndl = objc.loadBundle("CoreGraphics", global(), >>> bundle_path=p) >>> d = {} >>> objc.loadBundleVariables(bndl, d, >>> [(u'kCGErrorSuccess', objc._C_??), >>> (u'CGDirectDisplayID', objc._C_??)] >>> >>> I am having trouble figuring out the appropriate >>> signatures for these variables/contants. For >> example, >>> CGDirectDisplayID is defined as typedef struct >>> _CGDirectDisplayID * CGDirectDisplayID; in >>> >> > /System/Library/Frameworks/ApplicationServices.framework/Frameworks/ >> >>> CoreGraphics.framework/Headers/CGDirectDisplay.h; >>> but I can't find the struct definition of >>> _CGDirectDisplayID. Since it seems to be used only >> as >>> an opaque reference, what would it's objective c >>> typecode be? Also, kCGErrorSuccess is defined as 0 >> in >>> an enum called _CGError in >>> >> > /System/Library/Frameworks/ApplicationServices.framework/Frameworks/ >> >>> CoreGraphics.framework/Headers/CGError.h? >>> Is the typecode for this objc._C_UINT? Thanks. >> >> you can use objc._C_INT if you're sure it's pointer >> sized.. >> >> -bob >> >> >> >> > ------------------------------------------------------- >> This SF.Net email is sponsored by: IntelliVIEW -- >> Interactive Reporting >> Tool for open source databases. Create drag-&-drop >> reports. Save time >> by over 75%! Publish reports on the web. Export to >> DOC, XLS, RTF, etc. >> Download a FREE copy at >> http://www.intelliview.com/go/osdn_nl >> _______________________________________________ >> Pyobjc-dev mailing list >> Pyo...@li... >> > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev >> > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam protection around > http://mail.yahoo.com |
From: Ronald O. <ron...@ma...> - 2005-02-23 06:43:13
Attachments:
smime.p7s
|
On 22-feb-05, at 23:48, Bob Ippolito wrote: > > On Feb 22, 2005, at 17:40, Naveen Michaud-Agrawal wrote: > >> >> Thanks for your help earlier. I ported example worked >> fine. >> >> Now I am trying to call some CoreGraphics functions >> that return extra information by passing by reference. >> The problem is that I can't figure out the call >> signature for loadBundleFunctions, and also the >> appropriate way to call the function in python. Is >> there a byref function ala ctypes? > > No there isn't. ctypes works perfectly fine on OS X, so you could use > it. Depends on what he means by byref function ;-). I'm pretty sure that 'n' (in), 'o' (out) and 'N' (inout) are supposed to work as specifiers in signature strings. This definitely works for methods, e.g. "v@:n^i" is a method that has one byref integer argument, you'd call that as 'obj.someMethod_(1)'. The pointer argument must point to 1 value of the basic type, not to an array of them. Ronald |
From: Bob I. <bo...@re...> - 2005-02-23 07:20:25
|
On Feb 23, 2005, at 1:42 AM, Ronald Oussoren wrote: > > On 22-feb-05, at 23:48, Bob Ippolito wrote: > >> >> On Feb 22, 2005, at 17:40, Naveen Michaud-Agrawal wrote: >> >>> >>> Thanks for your help earlier. I ported example worked >>> fine. >>> >>> Now I am trying to call some CoreGraphics functions >>> that return extra information by passing by reference. >>> The problem is that I can't figure out the call >>> signature for loadBundleFunctions, and also the >>> appropriate way to call the function in python. Is >>> there a byref function ala ctypes? >> >> No there isn't. ctypes works perfectly fine on OS X, so you could >> use it. > > Depends on what he means by byref function ;-). I'm pretty sure that > 'n' (in), 'o' (out) and 'N' (inout) are supposed to work as specifiers > in signature strings. This definitely works for methods, e.g. "v@:n^i" > is a method that has one byref integer argument, you'd call that as > 'obj.someMethod_(1)'. The pointer argument must point to 1 value of > the basic type, not to an array of them. It's not quite equivalent. For example, how do you pass NULL to an in/out? If you pass None, you will end up with a pointer to a NULL value rather than NULL itself. If we did support a byref argument, we could get rid of the majority of the strange rules with arguments and return values... -bob |
From: Naveen Michaud-A. <inf...@ya...> - 2005-02-23 15:39:24
|
--- Bob Ippolito <bo...@re...> wrote: > > On Feb 23, 2005, at 1:42 AM, Ronald Oussoren wrote: > > > > > On 22-feb-05, at 23:48, Bob Ippolito wrote: > > > >> > >> On Feb 22, 2005, at 17:40, Naveen Michaud-Agrawal > wrote: > >> > >>> > >>> Thanks for your help earlier. I ported example > worked > >>> fine. > >>> > >>> Now I am trying to call some CoreGraphics > functions > >>> that return extra information by passing by > reference. > >>> The problem is that I can't figure out the call > >>> signature for loadBundleFunctions, and also the > >>> appropriate way to call the function in python. > Is > >>> there a byref function ala ctypes? > >> > >> No there isn't. ctypes works perfectly fine on > OS X, so you could > >> use it. > > > > Depends on what he means by byref function ;-). > I'm pretty sure that > > 'n' (in), 'o' (out) and 'N' (inout) are supposed > to work as specifiers > > in signature strings. This definitely works for > methods, e.g. "v@:n^i" > > is a method that has one byref integer argument, > you'd call that as > > 'obj.someMethod_(1)'. The pointer argument must > point to 1 value of > > the basic type, not to an array of them. > > It's not quite equivalent. For example, how do you > pass NULL to an > in/out? If you pass None, you will end up with a > pointer to a NULL > value rather than NULL itself. > > If we did support a byref argument, we could get rid > of the majority of > the strange rules with arguments and return > values... > > -bob OK, granted that was a made up call signature. What I'm really trying to do is write a program that can automatically tile an application's windows (particularly iTerm) in a way similar to the ion window manager for X11. For that I need to call some of the undocumented CoreGraphics functions to access other application's windows. Eventually it will be in rewritten in objective c, but for now I just want to test various tiling algorithms using pyobjc. For a single byref argument I figured out the signature string and python call signature. For example, to call the following function to retrieve the current workspace extern OSStatus CGSGetWorkspace(const CGSConnection cid, int *workspace); the following seems to work: FUNCTIONS=[ ( u'_CGSDefaultConnection', 'oi'), \ ( u'CGSGetWorkspace', 'nioiN^i'), ] CoreGraphics = new.module("CoreGraphics") p = objc.pathForFramework(u'/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework') bndl = objc.loadBundle("CoreGraphics", CoreGraphics.__dict__, bundle_path=p) objc.loadBundleFunctions(bndl, CoreGraphics.__dict__, FUNCTIONS, skip_undefined=False) connection = CoreGraphics._CGSDefaultConnection() wid = 0 err, wid = CoreGraphics.CGSGetWorkspace(connection, wid) wid now seems to have the correct workspace number (I'm using Virtue Desktops - virtuedesktops.sourceforge.net - for multiple desktops) Now my next problem is that i need to pass in an array of ints by pointer to get a list of windows (assuming I already know the count): extern OSStatus CGSGetWorkspaceWindowList(const CGSConnection cid, int workspaceNumber, int count, int* list, int* outCount); How would I pass in a presized array of integers? Also, I noticed the byref typecode 'R' is not implemented. Naveen __________________________________ Do you Yahoo!? Yahoo! Mail - Find what you need with new enhanced search. http://info.mail.yahoo.com/mail_250 |
From: Bob I. <bo...@re...> - 2005-02-23 16:07:24
|
On Feb 23, 2005, at 10:39, Naveen Michaud-Agrawal wrote: > > --- Bob Ippolito <bo...@re...> wrote: > >> >> On Feb 23, 2005, at 1:42 AM, Ronald Oussoren wrote: >> >>> >>> On 22-feb-05, at 23:48, Bob Ippolito wrote: >>> >>>> >>>> On Feb 22, 2005, at 17:40, Naveen Michaud-Agrawal >> wrote: >>>> >>>>> >>>>> Thanks for your help earlier. I ported example >> worked >>>>> fine. >>>>> >>>>> Now I am trying to call some CoreGraphics >> functions >>>>> that return extra information by passing by >> reference. >>>>> The problem is that I can't figure out the call >>>>> signature for loadBundleFunctions, and also the >>>>> appropriate way to call the function in python. >> Is >>>>> there a byref function ala ctypes? >>>> >>>> No there isn't. ctypes works perfectly fine on >> OS X, so you could >>>> use it. >>> >>> Depends on what he means by byref function ;-). >> I'm pretty sure that >>> 'n' (in), 'o' (out) and 'N' (inout) are supposed >> to work as specifiers >>> in signature strings. This definitely works for >> methods, e.g. "v@:n^i" >>> is a method that has one byref integer argument, >> you'd call that as >>> 'obj.someMethod_(1)'. The pointer argument must >> point to 1 value of >>> the basic type, not to an array of them. >> >> It's not quite equivalent. For example, how do you >> pass NULL to an >> in/out? If you pass None, you will end up with a >> pointer to a NULL >> value rather than NULL itself. >> >> If we did support a byref argument, we could get rid >> of the majority of >> the strange rules with arguments and return >> values... > > OK, granted that was a made up call signature. What > I'm really trying to do is write a program that can > automatically tile an application's windows > (particularly iTerm) in a way similar to the ion > window manager for X11. For that I need to call some > of the undocumented CoreGraphics functions to access > other application's windows. Eventually it will be in > rewritten in objective c, but for now I just want to > test various tiling algorithms using pyobjc. > > For a single byref argument I figured out the > signature string and python call signature. For > example, to call the following function to retrieve > the current workspace > > extern OSStatus CGSGetWorkspace(const CGSConnection > cid, int *workspace); > > the following seems to work: > > FUNCTIONS=[ ( u'_CGSDefaultConnection', 'oi'), \ > ( u'CGSGetWorkspace', > 'nioiN^i'), > ] type specifiers (n, o, N) are only for pointer arguments... that's not a valid signature, I'm surprised PyObjC will accept it. It shouldn't. > CoreGraphics = new.module("CoreGraphics") > > p = > objc.pathForFramework(u'/System/Library/Frameworks/ > ApplicationServices.framework/Frameworks/CoreGraphics.framework') > bndl = objc.loadBundle("CoreGraphics", > CoreGraphics.__dict__, bundle_path=p) > > objc.loadBundleFunctions(bndl, CoreGraphics.__dict__, > FUNCTIONS, skip_undefined=False) > > connection = CoreGraphics._CGSDefaultConnection() > wid = 0 > err, wid = CoreGraphics.CGSGetWorkspace(connection, > wid) > > wid now seems to have the correct workspace number > (I'm using Virtue Desktops - > virtuedesktops.sourceforge.net - for multiple > desktops) > > Now my next problem is that i need to pass in an array > of ints by pointer to get a list of windows (assuming > I already know the count): > > extern OSStatus CGSGetWorkspaceWindowList(const > CGSConnection cid, int workspaceNumber, int count, > int* list, int* outCount); > > How would I pass in a presized array of integers? > > Also, I noticed the byref typecode 'R' is not > implemented. I'm pretty sure loadBundleFunctions can't do that. Use ctypes. >>> import ctypes >>> as = ctypes.CDLL('/System/Library/Frameworks/ApplicationServices.framework/ ApplicationServices') >>> as <CDLL '/System/Library/Frameworks/ApplicationServices.framework/ ApplicationServices', handle 90810000 at 41d78> >>> as.CGSGetWorkspaceWindowList <ctypes._CdeclFuncPtr object at 0x289e0> -bob |
From: Naveen Michaud-A. <inf...@ya...> - 2005-02-23 17:37:53
|
> > I'm pretty sure loadBundleFunctions can't do that. > Use ctypes. > > >>> import ctypes > >>> as = > ctypes.CDLL('/System/Library/Frameworks/ApplicationServices.framework/ > > ApplicationServices') > >>> as > <CDLL > '/System/Library/Frameworks/ApplicationServices.framework/ > > ApplicationServices', handle 90810000 at 41d78> > >>> as.CGSGetWorkspaceWindowList > <ctypes._CdeclFuncPtr object at 0x289e0> > > -bob > OK, everything works great using ctypes. So is there any benefit to using objc.loadBundleFunctions? Could it be updated to be as useful as ctypes so I wouldn't have to require an extra library? Naveen __________________________________ Do you Yahoo!? Yahoo! Mail - Helps protect you from nasty viruses. http://promotions.yahoo.com/new_mail |
From: Bob I. <bo...@re...> - 2005-02-23 17:45:59
|
On Feb 23, 2005, at 12:37, Naveen Michaud-Agrawal wrote: >> >> I'm pretty sure loadBundleFunctions can't do that. >> Use ctypes. >> >>>>> import ctypes >>>>> as = >> > ctypes.CDLL('/System/Library/Frameworks/ApplicationServices.framework/ >> >> ApplicationServices') >>>>> as >> <CDLL >> > '/System/Library/Frameworks/ApplicationServices.framework/ >> >> ApplicationServices', handle 90810000 at 41d78> >>>>> as.CGSGetWorkspaceWindowList >> <ctypes._CdeclFuncPtr object at 0x289e0> > > OK, everything works great using ctypes. So is there > any benefit to using objc.loadBundleFunctions? Could > it be updated to be as useful as ctypes so I wouldn't > have to require an extra library? The benefit to objc.loadBundleFunctions is that it understands Objective-C types very well, so it works great for the kind of functions you find in Objective-C frameworks. It is not a general solution to calling arbitrary C functions. It could be, but that's not an immediate goal and is quite unlikely to happen anytime soon (definitely not in PyObjC 1.3). -bob |
From: Ronald O. <ron...@ma...> - 2005-02-23 18:51:54
Attachments:
smime.p7s
|
On 23-feb-05, at 18:45, Bob Ippolito wrote: >> >> OK, everything works great using ctypes. So is there >> any benefit to using objc.loadBundleFunctions? Could >> it be updated to be as useful as ctypes so I wouldn't >> have to require an extra library? > > The benefit to objc.loadBundleFunctions is that it understands > Objective-C types very well, so it works great for the kind of > functions you find in Objective-C frameworks. It is not a general > solution to calling arbitrary C functions. It could be, but that's > not an immediate goal and is quite unlikely to happen anytime soon > (definitely not in PyObjC 1.3). As Bob said objc.loadBundleFunctions is there to make it easier to wrap ObjC frameworks. Reinventing ctypes is not a goad of PyObjC, although we might end up with simular capabilities in the future. Ronald |
From: Bill B. <bb...@ap...> - 2005-02-03 19:27:44
|
On Feb 3, 2005, at 11:22 AM, ufiedler wrote: > I am using pyobjc 1.2. I would highly recommend using PyObjC top-of-tree. It is very stable and there has been a lot of work related to KVC/KVO. |
From: Bob I. <bo...@re...> - 2005-02-05 07:01:35
|
On Feb 3, 2005, at 2:27 PM, Bill Bumgarner wrote: > On Feb 3, 2005, at 11:22 AM, ufiedler wrote: >> I am using pyobjc 1.2. > > I would highly recommend using PyObjC top-of-tree. It is very stable > and there has been a lot of work related to KVC/KVO. In this case it wouldn't have made a difference, the given code was incorrect. Though svn trunk is almost always very stable and does have lots of new features, the KVC/KVO related enhancements are largely just removing the need for objc.accessor in common cases (the validation methods will always need it, though, but that is it for PyObjC 1.3). -bob |