From: William S F. <ws...@fu...> - 2008-05-26 19:09:41
|
Nathan Ricci wrote: > Hi, I'm using swig to produce wrap a C interface for us in Python. I'm > having trouble wrapping a function with this header (if you're > wondering, I'm trying to wrap the Java Virtual Machine Tool Interface, > to write java debuggers in Python, because... well, I'm insane I > guess): > > struct JavaVM_ { > ... > jint GetEnv(void **penv, jint version); > ... > } > > Where the void **penv parameter is used to return by value. penv > should actually be of type > jvmtiEnv. So, in C, when using this function, it looks like (for example): > > jvmtiEnv *jvmti; > jint version=0; > > vm->GetEnv((void **)&jvmti, JVMTI_VERSION); > > So, when calling from python, I'd like it to look like this: > > vm.getEnv(version) > > and have it a return a tuple of the int and the jvmtiEnv. So, it seems > the wrapper must: > > -create a new jvmtiEnv > -cast it to get a pointer to a pointer of it > -cast it to void**, > -call GetEnv, > -and then wrap the result in python object > - and append that python object to the result tuple. > > But I'm not sure how to do this. I tried the following using typemaps: > > %typemap(in, numinputs=0) void** penv (jmtiEnv* temp){ > $1 = (void**)&temp; > } > > %typemap(argout) void** out { > PyObject *oldRes, *tuple, *env; > pVM = SWIG_NewPointerObj(SWIG_as_voidptr(vm), > SWIGTYPE_p_JavaVM_, 0 | 0); > > oldRes = $result; > env = SWIG_NewPointerObj(SWIG_as_voidptr(*out), > SWIGTYPE_p__JvmtiEnv, 0|0); > > > if(PyTuple_Check($result)){ > tuple = PyTuple_New(1); > PyTuple_SetItem(tuple, 0, env); > $result = PySequence_Concat($result, tuple); > Py_DECREF(tuple); > } > else{ > $result = PyTuple_New(2) > PyTuple_SetItem($result,0, oldRes); > PyTuple_SetItem($result,1, env); > Py_DECREF(oldRes); > } > > Py_DECREF(env); > > } > > But it doesn't even seem that swig applies this (that is, using this > has no effect on the wrapper c file). The typemap type and variable name must match the function being wrapped in order for swig to use it. So your 'in' typemap shown above should work, but the 'argout' typemap won't. The argout typemap targets void **out when it should be: %typemap(argout) void** penv { ... } > I'm sorry if my question is obvious, it maybe that I am just not > understanding typemaps correctly, but I have been staring at the > documentation a while and can't figure it out. Are type maps the > correct thing to use here? Yup typemaps is the right way to go. William |