Re: FFI question for Gregg

new topic     » goto parent     » topic index » view thread      » older message » newer message
ChrisB said...

Andy's SDL2 wrapper worked in the first version but unfortunately I seem to be getting an out of memory error. Not sure if there was something I was missing. Here's a bare minimum program that demos the issue.


produces the error

couldn't alloc 1795457776 bytes 
C:\EuProgramming\Euphoria4_1\libffi-euphoria\include\std\ffi.e:780 in function a 
Your program has run out of memory. 
One moment please... 

Good catch! That was definitely a bug. When creating a copy of the C_POINTER type for C_STRING it incorrectly overwrote the copied data with default values and this caused it to try and allocate a pointer's value worth of bytes. (Oops.) I've corrected in now. See commit #cfbf236.

Very important! Make sure you are now using define_c_union() for union types. This ensures the members "collapse" correctly so they all start at zero offset. Then use the nested types in the union to "typecast" the union when you peek/poke the members (see my example below). If you use define_c_struct() each of the members will be aligned sequentially in memory which is not what you want. You can see this if you print the sizeof() result. On my system (64-bit Ubuntu) using define_c_union() the sizeof(SDL_Event) is 24 bytes but using define_c_struct() the sizeof(SDL_Event) is 800 bytes!

-- declare the union 
public constant SDL_Event = define_c_union({ 
    C_UINT32, --type [1] 
--  (lots of types here) 
-- allocate the memory 
atom event = allocate_struct( SDL_Event ) 
-- (event loop or something here) 
-- "typecast" the union to SDL_CommonEvent to get common members 
atom eventtype = peek_member( event, SDL_CommonEvent, 1 ) 
atom timestamp = peek_member( event, SDL_CommonEvent, 2 ) 
if eventtype = SDL_DISPLAYEVENT then 
    -- "typecast" the union to SDL_DisplayEvent to read its members 
    atom displayid = peek_member( event, SDL_DisplayEvent, 3 ) 
    atom dispevent = peek_member( event, SDL_DisplayEvent, 4 ) 
elsif eventtype = SDL_WINDOWEVENT then 
    -- "typecast" the union to SDL_WindowEvent to read its members 
    atom windowid = peek_member( event, SDL_WindowEvent, 3 ) 
    atom winevent = peek_member( event, SDL_WindowEvent, 4 ) 
elsif eventtype = SDL_KEYDOWN or eventtype = SDL_KEYUP then 
    -- "typecast" the union to SDL_KeyboardEvent to read its members 
    atom windowid  = peek_member( event, SDL_KeyboardEvent, 3 ) 
    atom keystate  = peek_member( event, SDL_KeyboardEvent, 4 ) 
	atom keyrepeat = peek_member( event, SDL_KeyboardEvent, 5 ) 
else -- etc. 
end if 
free( event ) 
ChrisB said...

I made some small mods to you ffi.e


but I can't see how these would be an issue.

Don't bother modifying any of the boilerplate code inside of std/ffi.e. It's only there because I need to be keep std/ffi.e free of include statements to ensure my code doesn't inherit any side-effects from (or cause any side-effects to) the standard library. Once this goes into Euphoria all of that will go away and I will be using the standard library routines again. You should just use std/machine.e, std/types.e, etc.


new topic     » goto parent     » topic index » view thread      » older message » newer message


Quick Links

User menu

Not signed in.

Misc Menu