Re: Andrea Cini's euwingui
- Posted by jimcbrown (admin) Nov 13, 2010
- 3905 views
ChrisB said...
Hi
Yes, that's it - the return of one of the great tools.
Thanks Jim
Chris
There's a bug in the wrapper. The return values of v3_c_func() are passed in from a memory block allocated by 3.1.1 code, but after this is turned back into a 4.0 object, the block of RAM is never freed.
I can't compile a new dll.e right now, but here's the new euconvert.e and euconvertinc.e needed to fix this.
euconvertinc.e
include std/dll.e include std/machine.e include std/text.e include std/get.e constant thedll = open_dll("euconvert.dll"), v3_define_c_func_ = define_c_func(thedll, "v3_define_c_func", {C_POINTER}, C_INT), v3_define_c_proc_ = define_c_func(thedll, "v3_define_c_proc", {C_POINTER}, C_INT), v3_c_func_ = define_c_func(thedll, "v3_c_func", {C_INT, C_POINTER}, C_POINTER), v3_c_proc_ = define_c_proc(thedll, "v3_c_proc", {C_INT, C_POINTER}) v3_free_ = define_c_proc(thedll, "v3_free", {C_POINTER}) if find(-1, {thedll, v3_define_c_func_, v3_define_c_proc_, v3_c_func_, v3_c_proc_} ) then puts(1, "thedll, v3_define_c_func_, v3_define_c_proc_, v3_c_func_, v3_c_proc_\n") ? {thedll, v3_define_c_func_, v3_define_c_proc_, v3_c_func_, v3_c_proc_} puts(1, "error opening one of the above\n") abort(1) end if public function v3_define_c_func(atom dll, sequence name, sequence args, atom ret) sequence all = {dll, name, args, ret} all = sprint(all) atom addr = allocate_string(all) integer r = c_func(v3_define_c_func_, {addr}) free(addr) return r end function public function v3_define_c_proc(atom dll, sequence name, sequence args) sequence all = {dll, name, args} all = sprint(all) atom addr = allocate_string(all) integer r = c_func(v3_define_c_proc_, {addr}) free(addr) return r end function public function v3_c_func(integer func, sequence args) sequence all = sprint(args) atom addr = allocate_string(all) atom ret = c_func(v3_c_func_, {func, addr}) free(addr) all = peek_string(ret) -- since this was allocated by a v3 runtime, we need to make sure -- that it is freed by the same runtime that did the allocation c_proc(v3_free_, {ret}) all = value(all) return all[2] end function public procedure v3_c_proc(integer func, sequence args) sequence all = sprint(args) atom addr = allocate_string(all) c_proc(v3_c_proc_, {func, addr}) free(addr) end procedure
euconvert.e
include dll.e include get.e include misc.e include machine.e function peek_string(atom addr) sequence s integer c s = "" while 1 do c = peek(addr) if c = 0 then exit end if s &= c addr = addr + 1 end while return s end function function toobject(sequence s) if atom(s) then s = peek_string(s) end if s = value(s) if atom(s[2]) then s = "" else s = s[2] end if return s end function global function v3_define_c_proc(integer x) sequence s s = toobject(x) return define_c_proc(s[1], s[2], s[3]) end function global function v3_define_c_func(integer x) sequence s s = toobject(x) return define_c_func(s[1], s[2], s[3], s[4]) end function global function v3_c_func(integer i, integer x) sequence s s = toobject(x) i = allocate_string(sprint(c_func(i, s))) return i end function global procedure v3_c_proc(integer i, integer x) sequence s s = toobject(x) c_proc(i, s) end procedure global procedure v3_free(integer x) free(x) end procedure