AW: [C++-sig] Wrapping opaque pointers returned from API function s

Gottfried.Ganssauge at HAUFE.DE Gottfried.Ganssauge at HAUFE.DE
Fri Jan 10 11:22:27 CET 2003


Hi Dave,

I knew it was something simple (although not entirely obvious :-))

Thanks a lot,

Gottfried

> -----Ursprungliche Nachricht-----
> Von: David Abrahams [mailto:dave at boost-consulting.com]
> Gesendet: Donnerstag, 9. Januar 2003 18:59
> An: c++-sig at python.org
> Betreff: Re: [C++-sig] Wrapping opaque pointers returned from API
> functions
> 
> 
> Gottfried.Ganssauge at HAUFE.DE writes:
> 
> > I am trying to wrap an API like the following:
> > 	typedef struct workspace_ *workspace;
> >
> > 	workspace osr_init (const char *) { return 0; }
> > 	void osr_exit (workspace ws) { std::cerr << ws << std::endl; }
> >
> > My first attempt at wrapping that API was
> > 	BOOST_PYTHON_MODULE(_pyOSR)
> > 	{
> > 		def ("osr_init", &::osr_init, 
> return_value_policy<return_by_value>());
> > 		def ("osr_exit", &::osr_exit);
> > 	}
> >
> > That compiled fine, but (of course) failed miserably when 
> run with the
> > following test script:
> > 	import _pyOSR
> >
> > 	ws = _pyOSR.osr_init(".")
> > 	print ws
> > 	_pyOSR.osr_exit(ws)
> >
> > Here is the traceback:
> > Traceback (most recent call last):
> >   File
> > 
> "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Releas
> e\test.py",
> >  line 3, in ?
> >     ws = _pyOSR.osr_init(".")
> > TypeError: No to_python (by-value) converter found for C++ 
> type: struct workspace_ *
> 
> Right.  You asked it to dereference the workspace_ pointer and return
> a copy of the result inside a Python object.
> 
> > Now I thought: ok, let's register a converter
> >     extern "C" void
> >     dealloc(PyObject* self) {
> >         PyObject_Del(self);
> >     }
> >
> >     struct workspace_wrapper : PyObject { workspace x; };
> >
> >     PyTypeObject workspaceType = {
> >         PyObject_HEAD_INIT(NULL)
> >         0,
> >         "workspace",
> >         sizeof(workspace_wrapper),
> >         0,
> >         dealloc
> >     };
> >
> >     struct p_from_workspace {
> >         static workspace &execute (workspace_wrapper &p_) {
>                  ^^^^^^^^^^^
> Should be        workspace_&
> 
> >             return p_.x;
> 
> Likewise, should be return *p_.x;
> [see caveat below]
> 
> >         }
> >     };
> >
> >     struct pworkspace_to_python
> >         : to_python_converter<workspace, pworkspace_to_python>
> >     {
> >         static PyObject* convert(workspace x) {
> >             workspace_wrapper *o =
> >                 PyObject_New (workspace_wrapper, &workspaceType);
> >             o->x = x;
> >             return ((PyObject*) o);
> >         }
> >     };
> >
> >     BOOST_PYTHON_MODULE(_pyOSR)
> >     {
> >         pworkspace_to_python();
> >         lvalue_from_pytype<p_from_workspace, &workspaceType>();
> >
> >         def ("osr_init", &::osr_init, 
> return_value_policy<return_by_value>());
> >         def ("osr_exit", &::osr_exit);
> >     }
> >
> > This time the output changed:
> > <workspace object at 0x00768EA0>
> > Traceback (most recent call last):
> >   File
> > 
> "C:\daten\devel\sourcecode-cd\OptiSearch\src\pyOSR\msvc\Releas
> e\test.py",
> >  line 5, in ?
> >     _pyOSR.osr_exit(ws)
> > TypeError: bad argument type for built-in operation
> >
> > The call to osr_init() succeeded and produced the expected result: a
> > workspace object.
> > Unfortunately the library is unable to find the proper converter for
> > converting that object back to my workspace pointer. I'm 
> sure, there is
> > something obvious I'm doing wrong, but what?
> 
> I'm impressed with how close you got, especially considering that most
> of the tools you had to use are undocumented!
> 
> When converting from_python to a C++ pointer type, the library looks
> for an lvalue converter for the *pointee*.  In other words, to convert
> to a Foo*, the source Python object must contain a Foo.
> 
> Obviously, wrapping opaque pointers is a common thing to want to do,
> and the library should provide a better facility for it.
> 
> Caveat: The code I've suggested above technically invokes undefined
> behavior if p_.x is 0, but I'm not aware of any platform which will
> have a problem with it.
> 
> -- 
>                        David Abrahams
>    dave at boost-consulting.com * http://www.boost-consulting.com
> Boost support, enhancements, training, and commercial distribution
> 
> 
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20030110/1f19d4bc/attachment.htm>


More information about the Cplusplus-sig mailing list