Length prefixed strings in C
Copy function improvements

Your copy function could be better:


   void PLS_copy(PLS *to,PLS *from) {
       int tc = from-&gt; curlen; // chars to copy
       if(tc &gt; to-&gt;maxlen) tc = to-&gt;maxlen;
       memcpy(to-&gt;buf,from-&gt;buf,tc);
   }




You could use const on your from argument.
You never update the length of the to string.  I'm assuming this is like a strcpy, so the to string should have its length set to the length that you just copied.


Here is how I would write it:

   void PLS_copy(PLS *to, const PLS *from)
   {
       uint8_t bytesToCopy = from-&gt;curlen;

       if (bytesToCopy &gt; to-&gt;maxlen)
           bytesToCopy = to-&gt;maxlen;
       memcpy(to-&gt;buf, from-&gt;buf, bytesToCopy);
       to-&gt;curlen = bytesToCopy;
   }


Flexible array member

I agree with the comment by M.M about using flexible array members instead of buf[1]:

typedef struct PLS { 
   uint8_t maxlen; 
   uint8_t curlen; 
   char buf[];  // actual allocated size is in maxlen 
} PLS;

struct {
    ...
    PLS s1;   // real allocated size: 100
    char s1buf[100];
    PLS s2;  // real allocated size: 64 
    char s2buf[64];
    ...
};


Also, you could use a macro to help declare these fields.  Something like this:

#define PLS_FIELD(name, length)  \
    PLS name;                    \
    char name##buf[length]


Then you could define your struct as:

struct {
    ...
    PLS_FIELD(s1, 100);
    PLS_FIELD(s2, 64);
    ...
};


Casting literal

For your literal casting, I would do this:

char lit1[] = "\x05\x05hello";
const PLS *lit1Pls = (const PLS *) lit1;


The const keyword here will prevent you from writing to the literal.  And the cast I used is simpler than the one you used.  I don't see anything objectionable about doing this.