conversion of Cstring to BYTE

13,767

Solution 1

The CString type is a template specialization of CStringT, depending on the character set it uses (CStringA for ANSI, CStringW for Unicode). While you ensure to use a matching encoding when constructing from a string literal by using the _T macro, you fail to account for the different size requirements when copying the controlled sequence to the buffer.

The following code fixes the first part:

CString data = _T("OK");
size_t size_in_bytes = (data.GetLength() + 1) * sizeof(data::XCHAR);
std::vector<BYTE> buffer(size_in_bytes);
unsigned char const* first = static_cast<unsigned char*>(data.GetString());
unsigned char const* last = first + size_in_bytes;
std::copy(first, last, buffer.begin());

The second question is really asking to solve a solved problem. The CStringT type already provides a CStringT::Compare member, that can be used:

const LPBYTE lpBuffer;
CString rcvValue(static_cast<char const*>(lpBuffer));
if (rcvValue.Compare(_T("ABC")) == 0)
{
    ////
}

General advice: Always prefer using the concrete CStringT specialization matching your character encoding, i.e. CStringA or CStringW. The code will be much easier to read and reason about, and when you run into problems you need help with, you can post a question at Stack Overflow, without having to explain, what compiler settings you are using.

Solution 2

Make sure you include atlstr.h to provide the definition of CString, as below:

#include "stdafx.h"
#include <Windows.h>
#include <atlstr.h>

int _tmain(int argc, _TCHAR* argv[])
{
    CString data = _T( "OK");
    LPBYTE pByte = new BYTE[data.GetLength() + 1];
    memcpy(pByte, (VOID*)LPCTSTR(data), data.GetLength());
    return 0;
}

Solution 3

I'm fairly certain Jay is correct for your first question. You need to include the right header.

For your second question, why would you expect that code to work? Let's walk through what the code you've written actually does.

  1. Create a char pointer (char *) without initializing it. This leaves lpData/lpBuffer pointing to a random location in memory.
  2. Create a CString and initialize it with this random pointer.
  3. Extract the buffer from the CString and compare it to a string literal.

Keeping in mind that the CString contains random garbage, what exactly do you expect this code to do? (Other than crash horribly? =) )

I also want to point out that you need to be more consistent in your approach to strings. Do you plan to support both char and wchar_t based strings as your use of TCHAR in the first sections suggests? Do you want to work with C-Style strings or do you want to use objects like CString? If you want to work with CString's, just use the Compare function that CString provides. Don't bother with strcmp.

Share:
13,767
Nabeel
Author by

Nabeel

Updated on June 04, 2022

Comments

  • Nabeel
    Nabeel almost 2 years

    I am using Visual Studio c++ and want to convert the Cstring to Byte. I have written this code but it gave me error in the second line that "data" is undefined.

    CString data = _T( "OK");
    LPBYTE pByte = new BYTE[data.GetLength() + 1];
    memcpy(pByte, (VOID*)LPCTSTR(data), data.GetLength());
    

    Further more I need to convert LPBYTE to const char for strcmp function. I have written the code but I can't find the issue with it.

    const LPBYTE lpBuffer;
    LPBYTE lpData = lpBuffer;
    CString rcvValue(LPCSTR(lpBuffer));
    const CHAR* cstr = (LPCSTR)rcvValue;
    if (strcmp (cstr,("ABC")) == 0)
    {
        ////
    }
    
  • Jay
    Jay over 11 years
    not me! I think someone else downvoted both of us, at least temporarily.
  • Gokul E
    Gokul E over 9 years
    this throws AccessViolationException
  • Hemaolle
    Hemaolle over 5 years
    Looks like the pByte BYTE array won't be large enough if Unicode is enabled since each char in the CString will take 2 BYTEs but data.GetLength() will return the number of characters.
  • IInspectable
    IInspectable over 5 years
    @gok: There is no AccessViolationException in C++, and if there were, the code wouldn't raise it. It still fails to account for size requirements of the character type used by CString (could be char or wchar_t), but that causes the string to get truncated. The behavior is still well defined.
  • IInspectable
    IInspectable over 5 years
    No, that won't work, for many reasons. When calling GetBuffer(), you are also required to call ReleaseBuffer() (or friends) later on. But you don't need a mutable pointer anyway, so just call GetString(). The code also fails to account for Unicode character encoding. CString could store characters encoded as UTF-16 (and that's the default in Visual Studio for many years), i.e. 2 bytes per code unit. Your code simply truncates such strings.