Re: ECW weird behavior
- Posted by Robert Craig <rds at RapidEuphoria.com> Oct 14, 2005
- 499 views
André Drummond wrote: > I´m using the GD library to create some gif images, and it seems not to work > when the program is translated to C (then compiled with Borland). > > The following function (from GD wrapper gd.e) could only work after I > introduced > the "if 1 then end if" statement below: > }}} <eucode> > global function gdImageCreateFromGif(sequence fd) > atom lpfd, ret, str, mode, oldmode > if equal(fd, GD_FILE_STDIO) then > if platform() = 2 then > oldmode = c_func(setmode, {0, #8000}) > end if > mode = allocate_string("rb") > lpfd = c_func(fdopen, {0, mode}) > else > str = allocate_string(fd) > mode = allocate_string("rb") > lpfd = c_func(fopen, {str, mode}) > free(str) > end if > free(mode) > if lpfd = 0 then > return 0 > end if > ret = c_func(GdImageCreateFromGif, {lpfd}) > str = c_func(fclose, {lpfd}) > > -- Look Here!!! > if 1 then end if > -- > > if equal(fd, GD_FILE_STDIO) and platform() = 2 then > oldmode = c_func(setmode, {0, oldmode}) > end if > return ret > end function > </eucode> {{{ > > The same thing happens with this other procedure (also in gd.e): > > }}} <eucode> > global procedure gdImageGif(gdImagePtr im, sequence out) > atom lpfd, str, mode, oldmode > if equal(out, GD_FILE_STDIO) then > if platform() = 2 then > oldmode = c_func(setmode, {1, #8000}) > end if > mode = allocate_string("wb") > lpfd = c_func(fdopen, {1, mode}) > else > str = allocate_string(out) > mode = allocate_string("wb") > lpfd = c_func(fopen, {str, mode}) > free(str) > end if > free(mode) > if lpfd = 0 then > return > end if > c_proc(GdImageGif, {im, lpfd}) > str = c_func(fclose, {lpfd}) > > -- Look Here!!! > if 1 then end if > -- > > if equal(out, GD_FILE_STDIO) and platform() = 2 then > oldmode = c_func(setmode, {1, oldmode}) > end if > end procedure > </eucode> {{{ > If I run the program with exw it works fine, but if I translate it them is > doesn´t > work... I narrow down the bug to those two pieces of code presented. By > bebugging > it I see that any usual command before the "Look Here!!!" points leads to an > machine error. > > Then, I desperately try to introduce the dummy line "if 1 then end if" and see > what happens then, for my surprise, it started to work. > > Does anyone have a clue of whats happening? The author of gd.e apparently forgot to specify the CDECL calling convention in his define_c_func()/proc() statements. Most .dlls, other than those written by Microsoft as part of the WIN32 API, use CDECL. In most cases, the Euphoria interpreter will handle CDECL correctly, even when it's declared incorrectly as STDCALL (the default). It will also work if you translate to C and compile with WATCOM. The error doesn't show up until you translate and compile with Borland (or Lcc). The solution is to add a "+" sign to all the define_c_func/proc calls that you depend on. e.g. in gd.e: GdImageCreateFromGif = define_c_func(GD_LIB, "gdImageCreateFromGif", ... becomes: GdImageCreateFromGif = define_c_func(GD_LIB, "+gdImageCreateFromGif", ... Also fclose() etc. You should let the author know about it. Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com