Newbie questions about Pliant

Newbie questions about Pliant

How can I use AllocatedCStr?

AllocatedCStr is defined in cstr.pli but the compiler complains when I try to use it.
Message posted by tfleming on 2001/03/04 04:40:08
I tried the following:

module "/pliant/language/unsafe.pli"
gvar AllocatedCStr a

The compiler says:

Failed to compile AllocatedCStr   ()
Message posted by maybe Hubert Tonneau on 2001/03/04 10:05:23
You should never use 'AllocatedCStr' type.
It is only intended to be used by the complex Pliant casting machinery to
allow automatic casting from 'Str' to 'CStr'.

Use 'Str' instead in your local and global variables,
and 'CStr' in the prototype of an external C function.
Message posted by maybe Todd Fleming on 2001/03/04 17:11:09
How should I handle C strings in structures that I pass to C functions?
Message posted by maybe Hubert Tonneau on 2001/03/04 18:27:44

Well, there is not a single answer:

Most C structures used to pass parameters to a function use 'inline' strings. I mean fixed length character sets, such as:

  char buffer[256];
For these, we would need to build a (CStr l) data type, where 'l' is the length of the fixed length characters set in the structure, just like we currently have (Array t l).

Now, if the field is a real string, such as:

  char *buffer;
then you might be right about the need to used 'AllocatedCStr', provided the field will be filled by Pliant and read by the C function.
Just put 'public' ahead of 'AllocatedStr' definition, just as for 'CStr' definition, then recompile the PDEE.

From a general point of view:

At the beginning, I had no 'CStr' definition in Pliant, so I was using '(Array Char xxx)' or 'Address' data types, with a bit of extra glue code per function.
'CStr' was introduced as a result of John Eikenberry attempting to interface an external DLL, in order to avoid glue code.

So, if you have extra needs, then post the exact C definition of the structure you need to share between Pliant an C code, plus the syntax and meaning of the function using it (specifying if the fields are read only in the function, read write, or write only, what the C prototype does not always specify), then we can study creation of additional modules that enable no glue code interface.

The general problem is that C is too low level in strings handling area, so people started to use tricks in order to avoid heavy code (or get better performances) such as using fixed length inline strings.
Now, when interfacing with another language, these very C specific tricks have to be reversed, so it's a bit of borring code to write, but Pliant expression power should be enough to cover various cases nearly transparently.

Message posted by maybe Todd Fleming on 2001/03/04 20:01:17

Here is the structure I am passing to a C function (CreateWindowEx):

  typedef struct _WNDCLASSEX { 
      UINT       cbSize; 
      UINT       style; 
      WNDPROC    lpfnWndProc; 
      int        cbClsExtra; 
      int        cbWndExtra; 
      HINSTANCE  hInstance; 
      HICON      hIcon; 
      HCURSOR    hCursor; 
      HBRUSH     hbrBackground; 
      LPCTSTR    lpszMenuName; 
      LPCTSTR    lpszClassName; 
      HICON      hIconSm; 
  } WNDCLASSEX, *PWNDCLASSEX; 

LPCTSTR is just a typedef to a const char* for the ANSI version of the function. Both strings are allocated by the caller. The callee dosn't hold on to the pointers.

As a temporary measure I copied the definition of AllocatedCStr to my code and renamed it to WindowsCStr. The Plient type looks like this:

  type WindowClass
    packed
    field uInt size
    field uInt style
    field Address windowProc
    field Int classExtra
    field Int windowExtra
    field uInt instance
    field uInt icon
    field uInt cursor
    field uInt background
    field WindowsCStr menuName
    field WindowsCStr className
    field uInt smallIcon

I am now sucessfully calling Windows functions and have created a callback (other debate). Right now I have a simple window that draws a diagonal line.

Message posted by maybe Hubert Tonneau on 2001/03/04 21:47:11
Looks like making 'AllocatedCStr' public would nicely solve your problem.

Another solution, with glue code is:

type WindowClass
  packed
  ...
  field Address menuName
  field Address className
  ...

...
var WindowClass wc
var Str menu := "test[0]"
var Str class := "sample[0]"
wc menuName := menu characters
wc className := class characters
...