Re: undefine_c_func (was: memory profiling)
- Posted by Chris Bensler <bensler at nt.net> Nov 20, 2006
- 673 views
Pete Lomax wrote: > > On Sun, 19 Nov 2006 15:25:53 -0800, "Michael J. Sabal" > <guest at RapidEuphoria.com> wrote: > > >GTK 2.6 has a procedure that allows for a variable number of arguments, > >similar to the way printf does. define_c_proc does not allow for this. My > >next thought was to simply define the procedure with the correct number of > >arguments each time it's needed. Except, without a matching undefine to > >free the memory, we introduce a leak into the library. > Why not just store results from define_c_proc in a sequence? > Eg: > }}} <eucode> > object xXxxx > xXxxx = 0 > > global procedure Eu_xXxxx(sequence params) > integer l > atom p > l = length(params) > if atom(xXxxx) then > xXxxx=repeat(0,l) > elsif l>length(xXxxx) then > xXxxx&=repeat(0,l-length(xXxxx)) > end if > p = xXxxx[l] > if p=0 then > p = define_c_proc(lib,"Xxxx",repeat(C_POINTER,l),C_INT) > xXxxx[l] = p > end if > c_proc(p,params) > end procedure > </eucode> {{{ > > Regards, > Pete There is no need for these kinds of hacks, variadic functions are fairly simple to interface with once you know how. I'm mostly going from memory and a lack of available informaton, but.. All the params are stored as an array of INT's or DOUBLES, depending on the actual type of the argument. Types are promoted, so char/short -> INT and float -> DOUBLE It is the function's responsibility to know what the types of the arguments are supposed to be and how many. Eg printf's first argument is a format string which inherently specifies the types of the variable arguments via the format flags. Other functions typically will just expect a certain type for a given argument. Eg, a list of string pointers All variadic functions in C have to have at least one named argument, the last of which is the first element of the variadic array. To denote how many args are passed, 0-terminate the array. Some functions will determine the number of arguments from one of the arguments (normally a named argument or the first variadic or implicitly), but it will never hurt to 0-terminate the array. Here is a code example to give you an idea (untested/pseudo code, I doubt it will actually work, you will likely need to experiment a bit as I have not dealt with variadic functions much or in a long time)
constant xcprintf = define_c_proc(DLL,"printf",{UINT}) procedure cprintf(object format, sequence args) atom lpargs,lp args = {format} & args lpargs = allocate(8*(length(args)+1)) -- allocate maximum size.. +1 for NULL terminator lp = lpargs for i = 1 to length(args) do if sequence(args[i]) then poke4(lp, allocate_string(args[i])) lp += 4 elsif (args[i] < #100000000) and (floor(args[i]) = args[i]) then -- int poke4(lp,args[i]) lp += 4 else -- float poke(atom_to_float64(args[i])) lp += 8 end if end for c_proc(cprintf,{lpargs}) lp = lpargs for i = 1 to length(args) do if sequence(args[i]) then free(lp) lp += 4 elsif (args[i] < #100000000) and (floor(args[i]) = args[i]) then -- int lp += 4 else -- float lp += 8 end if end for free(lpargs) end procedure
HTH Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria