From: <gg...@ad...> - 2007-10-14 08:38:12
|
Gonzalo Garramuno wrote: > This is a sample of how you would do it. Depending on how your api > works, you may need to change some stuff. > > // output_helper is a simple macro to easily concatenate stuff > %typemap(argout, fragment="output_helper") sqlite3 ** ( VALUE ary, > sqlite3** tmp ) > { > ary = rb_ary_new(); > > tmp = $1; > > // we assume the array ends in NULL and not that you need to > // know the size > for (; *tmp; ++tmp ) > { > // We assume here swig should not need to free the array > // Use SWIG_POINTER_OWN to have swig free it > rb_ary_push( ary, SWIG_NewPointerObj( *tmp, > SWIG_p_sqlite3, 0 ) ); > } > > // concatenate this argout array to the other result > $result = output_helper( $result, ary ); > } > Yehuda Katz wrote: > I don't understand why that would work (of course, I'm a newb). > > What does this: %typemap(argout, fragment="output_helper") sqlite3 ** ( > VALUE ary, sqlite3** tmp ) > mean exactly? Well, did you read the manual? That reads: - create a typemap for sqlite3** that returns it from a function parameter anywhere. Use temporary ary and tmp variables and include a fragment macro called output helper. The typemap is the code to translate from C to ruby for that particular type (sqlite3**). The makes your function work like: func(same C parameters) returns [ int, array of sqlite3s ] > > How does this solution handle the fact that my output is in my input > params (and obviously, I don't want to have to pass in a sqlite ** into > the function, I want the Ruby function to work like sqlite3_open("db"), > and have it return [0, swig wrapper around sqlite *]). > It is argout so the output is appended to the normal output in an array. If you also want to avoid passing an additional parameter, you should add a: %typemap(in, numinputs=0 ) sqlite3** {} > Is %apply the wrong solution here, because it seemed like it would work, > but I couldn't quite figure out how to set up the OUTPUT params. > %apply just applies a generic or named typemap to another symbol. If you define the typemap as I told you above, it would work fo ALL sqlite3's found in ALL your functions. You might want to limit that. So, you can define any of the typemaps adding a named parameter like: %typemap(in, ....) sqlite3** HELLO { ... } %typemap(argout,...) sqlite3** HELLO { ... } That would apply the typemap only to functions taking "sqlite3** HELLO" as parameter. With %apply, you can then make: %apply sqlite3** HELLO { sqlite3** pDB }; That makes sqlite3** pDB use the same rules as sqlite3** HELLO. If your .h files contain well named parameters, this is very useful to constraint the typemap to act on only one or a small group of functions. The "typemaps.i" file shipped with swig contains %typemaps for basic types for input, output and inout called INPUT, OUTPUT and INOUT parameters for basic C/C++ types. Thus you can then do %apply int* INPUT { int* x }; Thus, in the above case for sqlite3*, you probably would name the parameter OUTPUT instead of HELLO to easily point out what the two typemaps you wrote do. -- Gonzalo Garramuño Film Aura A New Dawn in Media Companies gg...@fi... http://www.filmaura.com |