How to pass a struct to an unsigned char array 
Author Message
 How to pass a struct to an unsigned char array

typedef struct _Blob
{
unsigned long dwKeyLen;
unsigned char* pbKey;
unsigned long dwDataLen;
unsigned char* pbData;

Quote:
} Blob;

int f1(unsigned char ** pbBuffer, unsigned long dwBufferLen)
{
Blob * sBlob = malloc (sizeof Blob);
unsigned long dwBlobSize = 0;

sBlob->dwKeyLen = 140;
sBlob->pbKey = "This is the key";
sBlob->dwDataLen = 16;
sBlob->pbData = "This is the message";

// How can I pass the whole struct to *pbBuffer?

// I have tried with this one... but the output was not the expected one
(random bytes)...
dwBlobSize = sizeof(unsigned long)*2 + sBlob->dwKeyLen + sBlob->dwDataLen;
*pbBuffer = realloc (*pbBuffer, dwBlobSize );
memcpy (*pbBuffer, sBlob, dwBlobSize);

free (sBlob);

Quote:
}

--
Carlo


Fri, 03 Dec 2004 09:53:55 GMT  
 How to pass a struct to an unsigned char array

Quote:
> typedef struct _Blob

Identifiers that begin with an underscore followed by an upper
case letter are always reserved for any use.  You should not use
them in your own code.

Quote:
> {
> unsigned long dwKeyLen;
> unsigned char* pbKey;
> unsigned long dwDataLen;
> unsigned char* pbData;
> } Blob;

> int f1(unsigned char ** pbBuffer, unsigned long dwBufferLen)
> {
> Blob * sBlob = malloc (sizeof Blob);

When calling malloc(), I recommend using the sizeof operator on
the object you are allocating, not on the type.  For instance,
*don't* write this:

        int *x = malloc (sizeof (int) * 128); /* Don't do this! */

Instead, write it this way:

        int *x = malloc (sizeof *x * 128);

There's a few reasons to do it this way:

        * If you ever change the type that `x' points to, it's not
          necessary to change the malloc() call as well.

          This is more of a problem in a large program, but it's still
          convenient in a small one.

        * Taking the size of an object makes writing the statement
          less error-prone.  You can verify that the sizeof syntax is
          correct without having to look at the declaration.

Quote:
> unsigned long dwBlobSize = 0;

> sBlob->dwKeyLen = 140;
> sBlob->pbKey = "This is the key";
> sBlob->dwDataLen = 16;
> sBlob->pbData = "This is the message";

> // How can I pass the whole struct to *pbBuffer?

You can't "pass" anything to a parameter.  You can assign to it,
though.

I think you probably want to just write
        *pbBuffer = (unsigned char *) sBlob;
but it's hard to tell since you don't say what pbBuffer is for
or explain why you're trying to use a Blob as a character buffer.
Also, dwBufferLen is never used by the function.

Quote:
> // I have tried with this one... but the output was not the expected one
> (random bytes)...
> dwBlobSize = sizeof(unsigned long)*2 + sBlob->dwKeyLen + sBlob->dwDataLen;
> *pbBuffer = realloc (*pbBuffer, dwBlobSize );
> memcpy (*pbBuffer, sBlob, dwBlobSize);

Do you understand that the compiler is allowed to insert padding
between and after struct members?

Quote:
> free (sBlob);
> }

--
"The expression isn't unclear *at all* and only an expert could actually
 have doubts about it"
--Dan Pop


Fri, 03 Dec 2004 09:59:29 GMT  
 How to pass a struct to an unsigned char array


Quote:
> I think you probably want to just write
>         *pbBuffer = (unsigned char *) sBlob;

This won't work. This can only return the first 'byte' of sBlob.

Quote:
> but it's hard to tell since you don't say what pbBuffer is for
> or explain why you're trying to use a Blob as a character buffer.
> Also, dwBufferLen is never used by the function.

sBlob in fact in my original code is for storing the key length, the key
bytes, the cipher text length and the cipher text. The function should be
able to return all those 'bytes' to *pbBuffer.
After the assignment from sBlob, *pbBuffer should have the same byte
sequence of sBlob's members (as far as I could say) i.e. *((unsigned
char*)*pbBuffer) should be equal to sBlob->dwKeyLen and so on...
Yes, dwBufferLen is in the orginal code but has no use in this snippet.

Quote:
> Do you understand that the compiler is allowed to insert padding
> between and after struct members?

How can I eliminate padding?

Thanks,

Carlo



Fri, 03 Dec 2004 10:36:27 GMT  
 How to pass a struct to an unsigned char array

Quote:


> > I think you probably want to just write
> >         *pbBuffer = (unsigned char *) sBlob;

> This won't work. This can only return the first 'byte' of sBlob.

You obviously don't know C, if that's what you think.

Quote:
> > but it's hard to tell since you don't say what pbBuffer is for
> > or explain why you're trying to use a Blob as a character buffer.
> > Also, dwBufferLen is never used by the function.

> sBlob in fact in my original code is for storing the key length, the key
> bytes, the cipher text length and the cipher text. The function should be
> able to return all those 'bytes' to *pbBuffer.

Which my suggested assignment will do.  It assigns a pointer (not
a byte, as you think) to the structure you allocated with
malloc() into *pbBuffer.

Quote:
> > Do you understand that the compiler is allowed to insert padding
> > between and after struct members?

> How can I eliminate padding?

You cannot.  You'll have to avoiding using a structure, or copy
the structure member-by-member, or find some other approach.


Fri, 03 Dec 2004 10:43:03 GMT  
 How to pass a struct to an unsigned char array

Quote:



>> I think you probably want to just write
>>         *pbBuffer = (unsigned char *) sBlob;

> This won't work. This can only return the first 'byte' of sBlob.

Bzzt.  It's returning a pointer to the beginning of the struct,
as allocated by malloc().

Quote:
>> but it's hard to tell since you don't say what pbBuffer is for
>> or explain why you're trying to use a Blob as a character buffer.
>> Also, dwBufferLen is never used by the function.

> sBlob in fact in my original code is for storing the key length, the key
> bytes, the cipher text length and the cipher text. The function should be
> able to return all those 'bytes' to *pbBuffer.
> After the assignment from sBlob, *pbBuffer should have the same byte
> sequence of sBlob's members (as far as I could say) i.e. *((unsigned
> char*)*pbBuffer) should be equal to sBlob->dwKeyLen and so on...
> Yes, dwBufferLen is in the orginal code but has no use in this snippet.

>> Do you understand that the compiler is allowed to insert padding
>> between and after struct members?

> How can I eliminate padding?

memcpy() each part separately.

int func (...)
{
  Blob * foo = read_blob ();
  int first_len;
  int second_len;
  int total_len = -1;
  unsigned char *out = NULL;

  if (foo != NULL) {
     first_len  = (int) strlen (foo->pbKey) + 1;
     second_len = (int) strlen (foo->pbData) + 1;
     total_len  = (int) sizeof first_len + sizeof second_len +
                        first_len + second_len;
     if (NULL != (out = malloc (total_len))) {
         unsigned char *ucptr = out;
         memcpy (ucptr, &first_len, sizeof first_len);
         ucptr += sizeof first_len;
         memcpy (ucptr, foo->pbKey, first_len);
         ucptr += first_len;
         memcpy (ucptr, &second_len, sizeof second_len);
         ucptr += sizeof second_len;
         memcpy (ucptr, foo->pbData, second_len);
     }
     else {
         total_len = -1;
     }
  }
  *pbBuffer = out;
  return total_len;

Quote:
}

I assumed you wanted to copy the whole of each string, and not
just its pointer...


Fri, 03 Dec 2004 11:07:46 GMT  
 How to pass a struct to an unsigned char array



Quote:



> >> I think you probably want to just write
> >>         *pbBuffer = (unsigned char *) sBlob;

> > This won't work. This can only return the first 'byte' of sBlob.

> Bzzt.  It's returning a pointer to the beginning of the struct,
> as allocated by malloc().

I should pinpoint to my problem. How to assign an unsigned long value to an
unsigned char*? Should I reverse the byte order before doing that
(little-endian)?

Thanks,

Carlo



Fri, 03 Dec 2004 12:03:06 GMT  
 How to pass a struct to an unsigned char array

Quote:





> > >> I think you probably want to just write
> > >>         *pbBuffer = (unsigned char *) sBlob;

> > > This won't work. This can only return the first 'byte' of sBlob.

> > Bzzt.  It's returning a pointer to the beginning of the struct,
> > as allocated by malloc().

> I should pinpoint to my problem. How to assign an unsigned long value to an
> unsigned char*? Should I reverse the byte order before doing that
> (little-endian)?

Why do you want to assign an unsigned long to an unsigned char *?
Please explain the problem.
--
"What is appropriate for the master is not appropriate for the novice.
 You must understand the Tao before transcending structure."
--The Tao of Programming


Fri, 03 Dec 2004 12:07:40 GMT  
 How to pass a struct to an unsigned char array


Quote:
> > I should pinpoint to my problem. How to assign an unsigned long value to
an
> > unsigned char*? Should I reverse the byte order before doing that
> > (little-endian)?

> Why do you want to assign an unsigned long to an unsigned char *?
> Please explain the problem.

As I said in the previous message that I need the structure to hold the
length of the key, the key bytes, the length of the cipher text and the
cipher text bytes then all of the stuff should be assigned to an unsigned
char* (as a whole entity).

Carlo



Fri, 03 Dec 2004 12:23:32 GMT  
 How to pass a struct to an unsigned char array

Quote:


> > > I should pinpoint to my problem. How to assign an unsigned long value to
> an
> > > unsigned char*? Should I reverse the byte order before doing that
> > > (little-endian)?

> > Why do you want to assign an unsigned long to an unsigned char *?
> > Please explain the problem.

> As I said in the previous message that I need the structure to hold the
> length of the key, the key bytes, the length of the cipher text and the
> cipher text bytes then all of the stuff should be assigned to an unsigned
> char* (as a whole entity).

You're confused.  You don't want to assign an unsigned long to an
unsigned char *.  You want to construct a buffer with an unsigned
long, etc., in order, then assign the address of the buffer to an
unsigned char *.

Here is one way that such a thing could be done:

/* Put an unsigned long followed by an int into a character
   buffer and return the buffer, or a null pointer if memory
   cannot be allocated. */
unsigned char *
create_populated_buffer (unsigned long ul, int i)
{
  unsigned char *buf = malloc (sizeof ul + sizeof i);

  if (buf != NULL) {
    unsigned char *p = buf;
    memcpy (p, &ul, sizeof ul);
    p += sizeof ul;
    memcpy (p, &i, sizeof i);
    p += sizeof i;
  }

  return buf;

Quote:
}



Fri, 03 Dec 2004 12:34:17 GMT  
 How to pass a struct to an unsigned char array


Quote:
> Here is one way that such a thing could be done:

> /* Put an unsigned long followed by an int into a character
>    buffer and return the buffer, or a null pointer if memory
>    cannot be allocated. */
> unsigned char *
> create_populated_buffer (unsigned long ul, int i)
> {
>   unsigned char *buf = malloc (sizeof ul + sizeof i);

>   if (buf != NULL) {
>     unsigned char *p = buf;
>     memcpy (p, &ul, sizeof ul);
>     p += sizeof ul;
>     memcpy (p, &i, sizeof i);
>     p += sizeof i;
>   }

>   return buf;
> }

However, I could not get those values back in this way:

void release_buffer (unsigned char* buf)
{
    unsigned long ul = 0;
    int i = 0;

    ul = *(unsigned long*)buf;    // ul does not equal to the original value
    i = *(int*)buf;                      // i does not equal to the original
value

Quote:
}

Thanks,

Carlo



Fri, 03 Dec 2004 16:33:06 GMT  
 How to pass a struct to an unsigned char array

Quote:


> > Here is one way that such a thing could be done:

> > /* Put an unsigned long followed by an int into a character
> >    buffer and return the buffer, or a null pointer if memory
> >    cannot be allocated. */
> > unsigned char *
> > create_populated_buffer (unsigned long ul, int i)
> > {
> >   unsigned char *buf = malloc (sizeof ul + sizeof i);

> >   if (buf != NULL) {
> >     unsigned char *p = buf;
> >     memcpy (p, &ul, sizeof ul);
> >     p += sizeof ul;
> >     memcpy (p, &i, sizeof i);
> >     p += sizeof i;
> >   }

> >   return buf;
> > }

> However, I could not get those values back in this way:

> void release_buffer (unsigned char* buf)
> {
>     unsigned long ul = 0;
>     int i = 0;

>     ul = *(unsigned long*)buf;    // ul does not equal to the original value
>     i = *(int*)buf;                      // i does not equal to the original
> value
> }

There is no way to get what you want.


Sat, 04 Dec 2004 01:50:21 GMT  
 How to pass a struct to an unsigned char array



:> > Here is one way that such a thing could be done:
:> >
:> > /* Put an unsigned long followed by an int into a character
:> >    buffer and return the buffer, or a null pointer if memory
:> >    cannot be allocated. */
:> > unsigned char *
:> > create_populated_buffer (unsigned long ul, int i)
:> > {
:> >   unsigned char *buf = malloc (sizeof ul + sizeof i);
:> >
:> >   if (buf != NULL) {
:> >     unsigned char *p = buf;
:> >     memcpy (p, &ul, sizeof ul);
:> >     p += sizeof ul;
:> >     memcpy (p, &i, sizeof i);
:> >     p += sizeof i;
:> >   }
:> >
:> >   return buf;
:> > }
:> >
:>
:> However, I could not get those values back in this way:
:>
:> void release_buffer (unsigned char* buf)
:> {
:>     unsigned long ul = 0;
:>     int i = 0;
:>
:>     ul = *(unsigned long*)buf;
:>     i = *(int*)buf;      
:> value
:> }

: There is no way to get what you want.

Couldn't he just do the reverse of what you did in your create_populated_bufer()
function?  Something like (warning >> uncompiled, untested code):

unsigned long get_ul( unsigned char *buf )
{
    unsigned long ul = 0;

    memcpy( &ul, buf, sizeof ul );
    return ul;

Quote:
}

Then do the same for the int:

int get_int( unsigned char *buf )
{
    int i = 0;
    unsigned char *p;

    p = buf + sizeof(unsigned long);

    memcpy( &i, p, sizeof int );
    return i;

Quote:
}

Paul

--
Paul D. Boyle

North Carolina State University
http://laue.chem.ncsu.edu/web/xray.welcome.html



Sat, 04 Dec 2004 02:23:07 GMT  
 How to pass a struct to an unsigned char array

Quote:




> :> > Here is one way that such a thing could be done:
> :> >
> :> > /* Put an unsigned long followed by an int into a character
> :> >    buffer and return the buffer, or a null pointer if memory
> :> >    cannot be allocated. */
> :> > unsigned char *
> :> > create_populated_buffer (unsigned long ul, int i)
> :> > {
> :> >   unsigned char *buf = malloc (sizeof ul + sizeof i);
> :> >
> :> >   if (buf != NULL) {
> :> >     unsigned char *p = buf;
> :> >     memcpy (p, &ul, sizeof ul);
> :> >     p += sizeof ul;
> :> >     memcpy (p, &i, sizeof i);
> :> >     p += sizeof i;
> :> >   }
> :> >
> :> >   return buf;
> :> > }
> :> >
> :>
> :> However, I could not get those values back in this way:
> :>
> :> void release_buffer (unsigned char* buf)
> :> {
> :>     unsigned long ul = 0;
> :>     int i = 0;
> :>
> :>     ul = *(unsigned long*)buf;
> :>     i = *(int*)buf;      
> :> value
> :> }

> : There is no way to get what you want.

> Couldn't he just do the reverse of what you did in your create_populated_bufer()
> function?

Of course.  But he wants to store all of the data at the same
location in memory, like a union.  That's not going to work.
--
"The way I see it, an intelligent person who disagrees with me is
 probably the most important person I'll interact with on any given
 day."
--Billy Chambless


Sat, 04 Dec 2004 02:33:27 GMT  
 How to pass a struct to an unsigned char array

Quote:





>> :> > Here is one way that such a thing could be done:
>> :> >
>> :> > /* Put an unsigned long followed by an int into a character
>> :> >    buffer and return the buffer, or a null pointer if memory
>> :> >    cannot be allocated. */
>> :> > unsigned char *
>> :> > create_populated_buffer (unsigned long ul, int i)
>> :> > {
>> :> >   unsigned char *buf = malloc (sizeof ul + sizeof i);
>> :> >
>> :> >   if (buf != NULL) {
>> :> >     unsigned char *p = buf;
>> :> >     memcpy (p, &ul, sizeof ul);
>> :> >     p += sizeof ul;
>> :> >     memcpy (p, &i, sizeof i);
>> :> >     p += sizeof i;
>> :> >   }
>> :> >
>> :> >   return buf;
>> :> > }
>> :> >
>> :>
>> :> However, I could not get those values back in this way:
>> :>
>> :> void release_buffer (unsigned char* buf)
>> :> {
>> :>     unsigned long ul = 0;
>> :>     int i = 0;
>> :>
>> :>     ul = *(unsigned long*)buf;
>> :>     i = *(int*)buf;      
>> :> value
>> :> }

>> : There is no way to get what you want.

>> Couldn't he just do the reverse of what you did in your create_populated_bufer()
>> function?
> Of course.  But he wants to store all of the data at the same
> location in memory, like a union.  That's not going to work.

What is stopping him from doing this?
void release_buffer(unsigned char *buf) {
  unsigned long ul=0;
  int i=0;
  ul=*(unsigned long *)buf;
  i=*(int *)(buf+sizeof ul);

Quote:
}

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/
"Normal is what everyone else is, and you're not."
   - Dr. Tolian Soran


Sat, 04 Dec 2004 02:42:25 GMT  
 How to pass a struct to an unsigned char array

Quote:






> >> :> > Here is one way that such a thing could be done:
> >> :> >
> >> :> > /* Put an unsigned long followed by an int into a character
> >> :> >    buffer and return the buffer, or a null pointer if memory
> >> :> >    cannot be allocated. */
> >> :> > unsigned char *
> >> :> > create_populated_buffer (unsigned long ul, int i)
> >> :> > {
> >> :> >   unsigned char *buf = malloc (sizeof ul + sizeof i);
> >> :> >
> >> :> >   if (buf != NULL) {
> >> :> >     unsigned char *p = buf;
> >> :> >     memcpy (p, &ul, sizeof ul);
> >> :> >     p += sizeof ul;
> >> :> >     memcpy (p, &i, sizeof i);
> >> :> >     p += sizeof i;
> >> :> >   }
> >> :> >
> >> :> >   return buf;
> >> :> > }
> >> :> >
> >> :>
> >> :> However, I could not get those values back in this way:
> >> :>
> >> :> void release_buffer (unsigned char* buf)
> >> :> {
> >> :>     unsigned long ul = 0;
> >> :>     int i = 0;
> >> :>
> >> :>     ul = *(unsigned long*)buf;
> >> :>     i = *(int*)buf;      
> >> :> value
> >> :> }

> >> : There is no way to get what you want.

> >> Couldn't he just do the reverse of what you did in your create_populated_bufer()
> >> function?

> > Of course.  But he wants to store all of the data at the same
> > location in memory, like a union.  That's not going to work.

> What is stopping him from doing this?
> void release_buffer(unsigned char *buf) {
>   unsigned long ul=0;
>   int i=0;
>   ul=*(unsigned long *)buf;
>   i=*(int *)(buf+sizeof ul);
> }

Nothing.  Read what he wrote, though.  He wants to retrieve the
data in a way that won't work, period.


Sat, 04 Dec 2004 02:45:52 GMT  
 
 [ 21 post ]  Go to page: [1] [2]

 Relevant Pages 

1. How to pass a struct to an unsigned char array

2. Char* array to Unsigned Char*

3. Sorting a Huge Unicode File use strcmp(unsigned char *, unsigned char *)

4. Sorting a Huge Unicode File use strcmp(unsigned char *, unsigned char *)

5. Sorting a Huge Unicode File use strcmp(unsigned char *, unsigned char *)

6. bytes to unsigned char, unsigned short, unsigned int, ...

7. Transforming __value structs to unmanaged unsigned char[]

8. struct, pointer and (unsigned char *) problem

9. cast from struct to unsigned char*

10. Passing a char array[n] to a function expecting a char*

11. Import ActiveX with unsigned char as passing parameter

12. char, unsigned char, signed char

 

 
Powered by phpBB® Forum Software