Thread: Store 16 bit words in char array?

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    17

    Store 16 bit words in char array?

    Hey, this is my first post I have been a long time creeper, this place is an excellent resource.

    My problem is that I am sending data to a PCI card via a c++ console interface, and the data is only to be accepted in a char * buffer. However the data I am sending are all 16 bit blocks of data. I have been trying to find a way to put these values into a short [] array so each word has a unique index, and then cast this into a char [], so far I have been unsuccessful in finding anything...
    Is it even possible to make such a type cast? It makes my work much more difficult if I need to split up my 16 bit words into 2 bytes to fit in a char array...

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Why do you need to convert to a char*? Send the base address to the card and it can do what it wants with it.

    (If the answer is "because C++ complains about passing a short* instead of a char*", then use static_cast.)

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    17
    It needs to be a char* because the card comes with a very specific API that demands a char* in the sending/receiving functions
    I will try your recommendation, see how that goes. Thank you

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Prediluted View Post
    It needs to be a char* because the card comes with a very specific API that demands a char* in the sending/receiving functions
    That doesn't really have anything to do with the data on your end, just on their end. (EDIT: But admittedly, C++ demands that you pay homage to the type system with a cast.)
    Last edited by tabstop; 06-03-2011 at 09:58 AM.

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    17
    Thank you! It isn't complaining using the type_cast.
    I ended up with something like this:

    Code:
    void packetBuilder ( int count, string package ){
    	short int *pack = 0;    // Hex array of values
    	char *ch = "";            // Char array of same values
    	stringstream dataStream( package );
    
    	// Save 0-3 for other purposes
    
    	for ( int i = 4; i <= count+5; i++ ) {
    		dataStream >> hex >> pack [ i ];
    		ch[i] = static_cast<char>(pack[i]);
    	}
    
    	sendData ( ch );
    }

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you do
    Code:
    char *ch = "";
    then you're not allowed to do ch[i] = something later on. Apparently you got away with it, somehow, but I have no idea how. And if you do
    Code:
    short int *pack = 0;
    then you DEFINITELY are not allowed to do pack[i], ever. I am really really really surprised that you got away with that at all.

    You need to either use new (if you're being pedantic) or a VLA (if you're willing to deal with compiler extensions) to get memory to send down the pipe. And what about the first 6 bytes anyway?

    Something like this may be better:
    Code:
    void packetBuilder ( int count, string package ) {
        short int *pack = new short int[count+4]; //don't know why you have count+5 there at all
        stringstream dataStream( package );
    
        // Save 0-3 for other purposes
    
        for ( int i = 4; i < count+4; i++) {
            dataStream >> hex >> pack[i];
        }
        sendData (static_cast<char *>(pack));
        free(pack);
    }
    Last edited by tabstop; 06-03-2011 at 10:29 AM. Reason: forgot to clean up

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    17
    Hmm strange your way does make much more sense, they were originally not declared as any value but VS complained when compiled saying they were not initialized. The reason it is +5 is because who ever brilliantly designed this decided that when there is 1 hex value in the package the count is 0. So the minimum length is actually 5 (the 4 reserve spots + 1 piece of data).

    I am getting an error
    error C2440: 'static_cast' : cannot convert from 'short *' to 'char *'
    on this line :
    Code:
    sendData ( static_cast<char *>( pack ) );
    Which I find strange because if I do it index by index there were no complaints.
    Last edited by Prediluted; 06-03-2011 at 10:46 AM.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    We may have to do things a bit old-fashioned then:
    Code:
    sendData ((char *)pack);
    Someone will be along pretty soon to complain about endianness issues, so I might as well make the point: if your system and your PIC don't agree on endianness then things will get interesting.

  9. #9
    Registered User
    Join Date
    Jun 2011
    Posts
    17
    Interesting. I will give it a shot and send/receive some test packets on a loopback to see how it handles
    Is there any reason why it would not work by indiviually assigning each index? That does not error out..
    IE
    Code:
    ch[1] = static_cast<char *>( pack [1])

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Prediluted View Post
    Interesting. I will give it a shot and send/receive some test packets on a loopback to see how it handles
    Is there any reason why it would not work by indiviually assigning each index? That does not error out..
    IE
    Code:
    ch[1] = static_cast<char *>( pack [1])
    The original, with ch[i] = pack[i], works on the assumption that you don't want half your data. (For instance, if the short that was read in was 0x3579, all you're going to get is 0x79 when you cast it to char.)
    pack[1] is a short, not a short*, so casting it as a char * won't work (and then on the other side ch[1] is a char, not a char * as well). If you drop the *, you get same as above (half the data).

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    17
    And this line here wont drop any data? This is basically just some type casting trickery to get the API to take the argument? Once the card reads in the information I have a peice of equipment attached to the card that will be reading those 16 bit words from the card.
    Code:
    sendData ((char *)pack);

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Right. All the (char *) does is tell the compiler to pretend that pack is a char*. Thing to remember: when you pass an array to a function, you don't actually pass an array to the function. All you actually pass is the beginning address of the array, so as long as our bytes are continuous (which new promises they are) then that data can be accessed on the other side.

  13. #13
    Registered User
    Join Date
    Jun 2011
    Posts
    17
    Ok, so I shouldn't even bother to try and print the values in the char* because they will be all messed up right?

    On the flip side when data is coming back from the pci card (Also as a char* of short int (hex numbers) ) Do I simply change the pointer by something like:

    Code:
    short int receivedData = (short int*)buffer;
    Or is it more complicated then that?

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Prediluted View Post
    Ok, so I shouldn't even bother to try and print the values in the char* because they will be all messed up right?
    I have no idea what you mean by this. (EDIT: OH, if you mean you're trying to use cout to print the characters themselves (as opposed to the numeric value of the characters), then yes that's probably garbage.) Let's suppose, for fun, that we have an array of six shorts, 0x1234, 0x2345, 0x3456, 0x789a, 0x89ab, and 0x9abc. From your perspective, it looks like this:
    Code:
    +----+----+----+----+----+----+
    |1234|2345|3456|789a|89ab|9abc|
    +----+----+----+----+----+----+
    ^
    |
    +--- base address of array
    so that pack[0] is 0x1234, etc. When you pass that base address to your data thing, it gets reinterpreted as a bunch of characters, so now you have twelve bytes of this:
    Code:
    +--+--+--+--+--+--+--+--+--+--+--+--+
    |34|12|45|23|56|34|9a|78|ab|89|bc|9a|
    +--+--+--+--+--+--+--+--+--+--+--+--+
    ^
    |
    +---- base address
    The byte-swapping is the endianness I mentioned before -- most modern computers are little-endian, meaning the least significant bytes are stored first. But in any event, that's what you should see on the other end of the pipe. Now what the other end of the pipe is going to do with the data I have no idea, but that's what it should see.

    As to receiving, you first need to allocate memory for the buffer, then do something like
    Code:
    short int *interpreted_data = (short int *)char_pointer_of_received_data;
    assuming the data you get is supposed to be interpreted as short ints.
    Last edited by tabstop; 06-03-2011 at 12:27 PM.

  15. #15
    Registered User
    Join Date
    Jun 2011
    Posts
    17
    Is there any way to avoid the endianness? That will cause havock with my equipment haha. I suppose I could reverse the numbers before I send them in, then they would go through in the right order. but that seems unescasary.
    And yes I was talking about using cout on it, you stated it much more clearly then I did.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to store a char array into another char array?
    By DaNxTh3xMaNx in forum C Programming
    Replies: 4
    Last Post: 11-12-2010, 10:28 AM
  2. Flip words in a char array.
    By mherald81 in forum C Programming
    Replies: 21
    Last Post: 10-17-2010, 09:11 AM
  3. which variable can store words?
    By Hunterofman in forum C++ Programming
    Replies: 8
    Last Post: 04-28-2008, 05:59 PM
  4. char array of words
    By sujeet1 in forum C++ Programming
    Replies: 5
    Last Post: 05-25-2007, 07:27 AM
  5. How to randomize words in a char array?
    By fero45 in forum C++ Programming
    Replies: 2
    Last Post: 05-31-2002, 07:01 PM