问题
I am wrapping this lib with Python SWIG that has a function looking like this:
int set_option(Foo *foo, const char *name, void *value);
In the lib const char *name
is mapped to a type that I have access to look up: int
, char *
, char **
.
The wrapper code generated by default accepts only a wrapped void *
(naturally).
What is the best way to make the wrapped method accept any Python object as argument, and do the type checking, and Python to C conversion in my own C code?
My guess would be some kind of type map, but alas I cannot figure it out.
@Goodies
In [12]: lib.set_option(foo, "option", "value")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-4ccf706b5c50> in <module>()
----> 1 lib.set_option(foo, "option", "value")
TypeError: in method 'set_option', argument 3 of type 'void *'
回答1:
If you just want to pass a PyObject
to something using %extend
you can modify what you've got and simply write the following:
%extend Foo {
int set_option(const char *name, PyObject *value) {
// Here value is now a PyObject *, so work with that.
// $self is Foo *foo
return 0;
}
};
There's no need for a typemap and this function now accepts any Python input. What you do with it is up to you and if you retain the object you'll need increase the reference count.
回答2:
Turns out it was rather simple. I wanted value
as PyObject *
so I could type check and convert it myself. Here is the function i wanted to wrap:
int set_option(Foo *foo, const char *name, void *value);
This solution also makes it a method of class Foo
.
%extend Foo {
int set_option(const char *name, void *value) {
// Here value is now a PyObject *, so work with that.
// $self is Foo *foo
return 0;
}
};
%typemap(in) (void *value) {
$1 = (void *) $input;
};
来源:https://stackoverflow.com/questions/35124093/wrapping-a-void-argument-in-python-swig