Thread: [Pyobjc-dev] Passing objects between PyObjc and SWIG
Brought to you by:
ronaldoussoren
|
From: Kyle J. <osm...@gm...> - 2008-03-20 10:27:30
|
I have a C library (Cairo) which accesses Core Graphics. I've wrapped
it up in a SWIG binding so I can easily access it from Python.
Everything is great when calling functions in it and passing around
objects from Apple's CoreGraphics Python library (which they generated
with SWIG as well). However, when I switch from using Apple's
CoreGraphics to using PyObjc libraries (AppKit and Quartz) and try to
pass a CGContextRef from a PyObjC lib to the SWIG-wrapped library I
get errors because SWIG doesn't recognize the PyObjc wrapping of the
object.
So basically, I need to code something which converts the PyObjc
internal type to a SWIG-understandable internal type.
Here's the problem: I can't figure out where to dig around in PyObjc
to find the representation of "core-foundation class CGContextRef." Is
this something which is being generated automatically and not
hand-coded somewhere?
A semi-related question: if I'm getting objects of type PyObjCPointer
when I do not import the PyObjc Quartz lib, but then I get objects of
"actual" types ("core-foundation class CGContextRef" in this case)
when I include the PyObjc Quartz lib, is that an indication that I
_must_ include the Quartz lib?
>From my digging so far, I think that just dealing with PyObjCPointers
and SWIG would be relatively simple; I just have that nagging idea
that PyObjCPointers are results of errors though. :)
Thanks!
--
Kyle Johnson
|
|
From: Ronald O. <ron...@ma...> - 2008-03-20 14:06:11
Attachments:
smime.p7s
|
On 20 Mar, 2008, at 11:27, Kyle Johnson wrote: > I have a C library (Cairo) which accesses Core Graphics. I've wrapped > it up in a SWIG binding so I can easily access it from Python. > > Everything is great when calling functions in it and passing around > objects from Apple's CoreGraphics Python library (which they generated > with SWIG as well). However, when I switch from using Apple's > CoreGraphics to using PyObjc libraries (AppKit and Quartz) and try to > pass a CGContextRef from a PyObjC lib to the SWIG-wrapped library I > get errors because SWIG doesn't recognize the PyObjc wrapping of the > object. > > So basically, I need to code something which converts the PyObjc > internal type to a SWIG-understandable internal type. > > Here's the problem: I can't figure out where to dig around in PyObjc > to find the representation of "core-foundation class CGContextRef." Is > this something which is being generated automatically and not > hand-coded somewhere? Those types are automaticly generated. You can use the __cobject__() method on all Objective-C or CoreFoundation objects to get a Python CObject that wraps the raw pointer. That might be easier to convert to something that swig might understand. Ronald |
|
From: Ronald O. <ron...@ma...> - 2008-03-20 14:14:18
Attachments:
smime.p7s
|
On 20 Mar, 2008, at 11:27, Kyle Johnson wrote:
>
>
> A semi-related question: if I'm getting objects of type PyObjCPointer
> when I do not import the PyObjc Quartz lib, but then I get objects of
> "actual" types ("core-foundation class CGContextRef" in this case)
> when I include the PyObjc Quartz lib, is that an indication that I
> _must_ include the Quartz lib?
Yes. Which methods return a PyObjCPointer when you don't import Quartz?
>
>> From my digging so far, I think that just dealing with PyObjCPointers
> and SWIG would be relatively simple; I just have that nagging idea
> that PyObjCPointers are results of errors though. :)
PyObjCPointers are definitely something you don't want to use. They
are the last resort for wrapping an arbitrary C pointer and should
never occur when a library is properly wrapped.
Ronald
|
|
From: Kyle J. <osm...@gm...> - 2008-03-21 03:07:49
|
On Thu, Mar 20, 2008 at 7:14 AM, Ronald Oussoren <ron...@ma...> wrote: > Yes. Which methods return a PyObjCPointer when you don't import Quartz? As far as I know, just NSGraphicsContext.currentContext().graphicsPort() -- Kyle Johnson |
|
From: Kyle J. <osm...@gm...> - 2008-03-21 05:08:49
|
On Thu, Mar 20, 2008 at 7:05 AM, Ronald Oussoren <ron...@ma...> wrote:
>
> On 20 Mar, 2008, at 11:27, Kyle Johnson wrote:
> > So basically, I need to code something which converts the PyObjc
> > internal type to a SWIG-understandable internal type.
>
> Those types are automaticly generated.
>
> You can use the __cobject__() method on all Objective-C or
> CoreFoundation objects to get a Python CObject that wraps the raw
> pointer. That might be easier to convert to something that swig might
> understand.
Thank you for the info, Ronald. I think I'm going in the right
direction with this now.
I think there may be some wrapping still going on though with
__cobject__ as I'm getting invalid context errors from Core Graphics
(via Cairo).
I call the cairo function from Python like so:
ctx = NSGraphicsContext.currentContext().graphicsPort()
cairo.cairo_quartz_surface_create_for_cg_context(ctx.__cobject__(), 400, 400)
My wrapper code looks like this:
// definition of cairo function
cairo_surface_t *cairo_quartz_surface_create_for_cg_context
(CGContextRef cgContext, unsigned int width, unsigned int height);
// BEGIN: wrapper code (simplified)
CGContextRef arg1;
unsigned int arg2, arg3;
PyObject *obj0, *obj1, *obj2;
PyArg_ParseTuple(args,(char
*)"OOO:cairo_quartz_surface_create_for_cg_context",&obj0,&obj1,&obj2);
if( PyCObject_Check(obj0) ) {
// !!! something is wrong here; either the void ptr returned isn't for
// a CGContextRef or my typecasting/de-pointerizing is bad
arg1 = *(CGContextRef *) PyCObject_AsVoidPtr(obj0);
} else {
PyErr_SetString(PyExc_TypeError, "cgContext is not type PyCObject");
return NULL;
}
// [...] code for obj1/arg2, obj2/arg3
result = cairo_quartz_surface_create_for_cg_context(arg1,arg2,arg3);
// END: wrapper code (simplified)
This shouldn't be a Cairo issue. I have a identical C/Objective-C copy
of my program working without a problem.
--
Kyle Johnson
|
|
From: Ronald O. <ron...@ma...> - 2008-03-21 16:29:29
Attachments:
smime.p7s
|
On 21 Mar, 2008, at 6:08, Kyle Johnson wrote: > On Thu, Mar 20, 2008 at 7:05 AM, Ronald Oussoren <ron...@ma... > > wrote: >> >> On 20 Mar, 2008, at 11:27, Kyle Johnson wrote: >>> So basically, I need to code something which converts the PyObjc >>> internal type to a SWIG-understandable internal type. >> >> Those types are automaticly generated. >> >> You can use the __cobject__() method on all Objective-C or >> CoreFoundation objects to get a Python CObject that wraps the raw >> pointer. That might be easier to convert to something that swig >> might >> understand. > > > Thank you for the info, Ronald. I think I'm going in the right > direction with this now. > > I think there may be some wrapping still going on though with > __cobject__ as I'm getting invalid context errors from Core Graphics > (via Cairo). You are the first user of this API, but looking at the code I'd say say that the implementation of __cobject__ is obviously correct. Are your Cairo wrappers available somewhere? This would be easier to debug if I had access to the code. BTW. If you don't mind having a hard dependency on PyObjC you could drop SWIG and use PyObjC instead, with some luck without writing a line of C code. PyObjC can use the bridgesupport files generated by gen_bridge_metadata(1) on Leopard, and it should be possible to use that tool to generate an XML description of the cairo API's. Ronald |