Newbie questions about Pliant

Newbie questions about Pliant

Wrapping problem

I'm very new to pliant and got a problem with wrapping a function from SDL (www.libsdl.org).
Message posted by maybe Jan on 2001/05/07 18:05:16
C-Function I want to wrap:

SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);

The code on the pliant-side:

function SDL_SetVideoMode width height bpp flags -> surface
  arg Int width ; arg Int height ; arg Int bpp; arg uInt32 flags
  arg Address surface
  external sdl "SDL_SetVideoMode"

Error message:

Failed to compile SDL_SetVideoMode   (uInt rc  uInt rc  uInt rc  uInt rc) 
...
processor stack content is:
error_notify_fatal (ErrorID Str) +14
error_report +61
error_renotify (ErrorID Address Str) +39
. compile (Expression) +124
  file:./test.pli (internals) 9 1
. execute (Expression) +21
  file:./test.pli (internals) 9 1
. execute (ParserContext) +40
parser_filter_execute +322
pliant internal parse_one_token function (ParserContext) +468
compile_text (List Module) +256
pliant_load_module (Str Module Int Module) +942
???

My question: Is the wrapping code wrong, or is it something else?
Some other functions in SDL with return type won't compile either, others work fine.
Message posted by maybe hubert tonneau on 2001/05/07 19:10:06
I'd rather think of a prototype like this:

function SDL_SetVideoMode width height bpp flags -> surface
  arg Int width height bpp; arg uInt flags ; arg_RW SDL_Surface surface
  external sdl "SDL_SetVideoMode"

You must not 'uInt32' because it might be the same as 'unsigned int *' in C,
not 'unsigned int'.
The reason is that there are never fixed size arguments passed to a modern
processor; fixed size arguments exist in memory, not on the stack or in
a processor registers. When a C program uses one, it's simply buggy, and
most C compiler will silently ignore it (switch it to 'long' or 'unsigned long')
Message posted by maybe Jan on 2001/05/08 08:06:34
Thanks, it works now.

Now I wonder, how to wrap C-structs that have fixed size members. Something like:
typedef struct {
  Sint16 x, y;
  Uint16 w, h;
} SDL_Rect;

AFAIK, using Int16 and uInt16 would get me the correct size for the
structure, but then I have again the problem, that trying to access the 
members results in an error.
I can access them when using just "Int", but then the pliant objects are bigger, right?
Message posted by maybe hubert tonneau on 2001/05/08 09:13:05
Within structures, you must use fixed size fields (such as uInt16) and the
reason is that structures are stored in memory, not in processor registers.
From a general point of view, on a modern processor, casting as an example,
from uInt16 to uInt, always append when loading a value from memory. So,
if a field of structure is uInt16, then it will be transformed to uInt when
loading the field to a local variable.
As a extra conclusion, a local variable should always be uInt, never uInt16
because a local variable will be most time a register.

Now, the extra problem you can have with structures comes from extra padding
some C compilers may silently introduce. When a structure is nicely built
(any n bytes wide field starts on a n bytes boundary), no padding should be
introduced by C compilers so it should translate very easily to Pliant (just
like in your example).

Now, let's imagine that the C structure is:
typedef struct {
  unsigned short a;
  int b;
  unsigned short c; } Test;

Then some C compilers might implement it as:
  type Test
    packed # packed asks Pliant not to add any padding field
    field uInt16 a
    field Int b
    field uInt16 c
and some others to:
  type Test
    packed
    field uInt16 a
    field uInt16 pad1
    field Int b
    field uInt16 c
and some even more optimizing ones to:
  type Test
    packed
    field uInt16 a
    field uInt16 c
    field Int b
because the 4 bytes field 'b' is not aligned on a 4 bytes boudary in the
C structure.

Finaly, the problem is even worse with 64 bits compilers, and currently not
soved properly in Pliant because on a 32 bits processor C 'int' is 32 bits,
and on most 64 bits processors, C 'int' is 32 bits also, not 64 bits !
So, I should introduce 'CInt' and 'CuInt' Pliant data types that match C
'int' size in all cases, just like we already have 'CStr'.
Message posted by mujtaba on 2003/03/17 14:33:37
I also am working on bindings for SDL. 
Check http://pligame.sourceforge.net
Message posted by pom on 2003/03/19 07:23:16
Perhaps you should put a link on pligame.sourceforge.net to the project
page sourceforge.net/project/pligame.

-----------

when trying it, I got the following error:

pliant: relocation error: /usr/lib/libSDL.so: undefined symbol: pthread_mutexattr_init

I actually use SDL-1.2.5-1. Is it the good version ?
(Notice that the executable /pliant/SDL/examples/sample works well)

------------

Last, you should put it in 'pliant' subdirectory (i.e. in /pliant/pliant/),
but rather in /pliant.so that pliant core upgrades won't interfer with yours.
Message posted by mujtaba on 2003/03/19 18:30:37
You're not running this under FreeBSD are you? Because it looks like you don't 
have libpthread linked. I know redhat's glibc 2.0 has that exact function built
into it. Perhaps your distro is different? I've tested this under Redhat and
debian. And I know I don't make any references to that function in my code.

Try downloading and compiling the source at libsdl.org, then (without installing) 
set your LD_LIBRARY_PATH to the directory where the built libSDL.so is in. 
Try it without pthread support. Let me know if any of this fixes you problem. 
I'll update my site if it helps. Thanks!

BTW, is there a standard convention where user extensions go? Is that 
in /pliant.so ?    
Message posted by mujtaba on 2003/03/19 20:02:27
I put up a precompiled version of libSDL 1.2.5 without pthread support. You can
get it at the project site under "files". Unpack the archive,
and set your LD_LIBRARY_PATH to lib/. Still, compiling and installing from sources
is the best way. In fact, I'm developing and testing based on the stable sources. 

Message posted by pom on 2003/03/21 06:26:42
great!