Re: [Pyobjc-dev] Bridging NS and CF classes
Brought to you by:
ronaldoussoren
From: Jack J. <Jac...@or...> - 2003-01-09 22:24:27
|
On donderdag, jan 9, 2003, at 05:01 Europe/Amsterdam, bb...@ma... wrote: > On Wednesday, Jan 8, 2003, at 18:03 US/Eastern, Jack Jansen wrote: >> I think I would like the bridging to be done one-way, i.e. if >> something wants an NSArray and the argument isn't an NSArray it >> should try coercing the argument to an NSArray. One of the things >> that could be coerced is CF.CFArray. >> >> I think that for going the other way (from NS to CF) manual >> conversion is probably good enough initially. > > Won't work as there is no class identification on the arguments to > methods. Ah, you're right of course, silly me... But that doesn't really matter: the PyObjC code could look at the type of the Python object and pass any CoreFoundation object as the corresponding NS object still. > Why can't we add enough stuff to both the CF* module(s) and the PyObjC > bridge such that both can transparently consume objects from the > other, where appropriate. Yes. Except that it is easy for PyObjC to get access to Python's CF module (the bridge is in the core) and the other way around is difficult. So I would like an initial implementation to be in PyObjC for that reason. And hopefully for Python 2.5 PyObjC will be part of the core so the problem will disappear:-) No, wait! I think the latter is doable too, see below. > This is basically what Apple did to ObjC and CF to create the > no-cost bridge -- it would seem that we need a parallel mechanism > within the "two" Python modules. > > That is, make the following work: > > >>> import _CF #this is framework build, why do I do this and not > "CF"?? > >>> x = _CF.CFArrayCreateMutable(10) > >>> from Foundation import NSMutableArray > >>> NSMutableArray.addObject_(x, 'y') > Traceback (most recent call last): > File "<stdin>", line 1, in ? > TypeError: First argument must be an objective-C object, got > <CFMutableArrayRef object at 0x0012c0e0 for 0x00160000> This is easy. If the argument isn't a PyObjC object then pass it to the C routine CFTypeRefObj_Convert(). If this succeeds you get back the C CF object and convert that to the corresponding NS object. > And so should this: > > >>> import _CF > >>> from Foundation import NSMutableArray > >>> x = NSMutableArray.array() > >>> _CF.CFArrayAppendValue(x, 'y') > Traceback (most recent call last): > File "<stdin>", line 1, in ? > AttributeError: 'module' object has no attribute 'CFArrayAppendValue' With some help from a PyObjC method and a little different syntax this is indeed doable, if all PyObjC objects had a Python method that would return themselves as a CF object. The Python sequence would become >>> import _CF >>> from Foundation import NSMutableArray >>> x = NSMutableArray.array() >>> _CF.CFMutableArray(x).CFArrayAppendValue('y') This would be implemented by having the CFArray() constructor look for a (say) "as_CF" [1] method and call that. as_CF() for PyObjC objects would do the cast to convert from an NS object to a CF object and then call the C routine CFTypeRefObj_New(), which returns the Python _CF object [2]. Footnotes: [1] I picked "as_CF" here in stead of something like "PyObjC_asCF" because I think this functionality may be useful to more sources of CF objects than only PyObjC, but this is open to discussion. [2] This won't work at the moment, as CFTypeRefObj_New will always return a CF.CFType object. Either this will have to change (which I think is reasonable: shortly CFArray will be a true subtype of CFType, and I think its reasonable for a constructor to return a "better" subtype) of we need to add a CFAny_New() routine. -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |