Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 495
  • Last Modified:

GetBuffer() on win CE

I want to copy some data from a char buffer into a CString. The following works great on VC++6 but does not work on windows CE.

char* dataBuff[1024];
loadDataIntoBuffer(dataBuff); //dataBuff has data

DWORD Pos = 10;

CString tmpStr = "";
LPTSTR pstr = tmpStr.GetBuffer(Pos); //addr of pstr is 0x0004bad4
memcpy( pstr,dataBuff,Pos); //value of pstr is "??????..."
tmpStr.ReleaseBuffer();

Why this doesn't work under winCE? is there a better way to copy retrieve data from a char buffer into a CString?

thanks in advance
0
el_rooky
Asked:
el_rooky
  • 17
  • 8
  • 7
  • +1
1 Solution
 
jhanceCommented:
Have you tried:

CString tmpStr = CString(dataBuff);

There is no need to use GetBuffer() and memcpy() since the CString contructor is perfectly able to make a CString from a char *.
0
 
el_rookyAuthor Commented:
I don't want to convert the entire dataBuff into a CString since dataBuff could be very large. How can I retreive only the first 10 characters or characters from location 10 to 20 of dataBuff ?
0
 
jhanceCommented:
Well, one approach would be to stuff a NULL terminator into the end of where you want the string copied from and pass CString's contructor the address of the beginning of the area you want to use.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
el_rookyAuthor Commented:
jhance,
could you give me an example please? Let say that I have the following:
char* dataBuff[1024];
CString str1 = "";
CString str2 = "";
I want to copy characters from location 0 to 10 into str1 and from 11 to 20 into str2.
How can I acomplish that using your sugested method?
0
 
jkrCommented:
What about

CString strData;
CString str1;
CString str2;

str1 = strData.Mid ( 0, 10);
str2 = strData.Mid ( 11, 20);

That's what the CString extraction methods are made for...
0
 
AxterCommented:
You could try the following minor modification:

char* dataBuff[1024];
loadDataIntoBuffer(dataBuff); //dataBuff has data

DWORD Pos = 10;

CString tmpStr = "xxxx";//Add some data here ****
LPTSTR pstr = tmpStr.GetBuffer(Pos); //addr of pstr is 0x0004bad4
memcpy( pstr,dataBuff,Pos); //value of pstr is "??????..."
tmpStr.ReleaseBuffer();

Instead of having tmpStr equal to "", make it equal to a small string less then Pos length.

By doing this, you force the CString object to actually assign a buffer.
0
 
jhanceCommented:
I think he indicated that the problem was that strData might be quite large.  On a "real" Windows machine that is probably not much of an issue but on CE it might kill the thing...
0
 
AxterCommented:
>>I think he indicated that the problem was that strData
>>might be quite large.

I'm not suggesting to add the target data.  I'm suggesting to put dummy data for the initialize field.
CString tmpStr = "blabla";//Add some dummy data here

The reason I'm suggesting this is that it could be posible that CString refferncing code is causing the problem.  If you assign data to CString from a string literal with (not-empty), then you'll fource CString to create it's own buffer when it initiates.

If you just assign "", CString will reference a built-in EmptyCString object, which is pointed to by every CString object that gets initiated with no data.
0
 
AxterCommented:
I just realized your code is not assigning enough space for the target data.
Try this:
char* dataBuff[1024];
loadDataIntoBuffer(dataBuff); //dataBuff has data

DWORD Pos = 10;

CString tmpStr = "";
LPTSTR pstr = tmpStr.GetBuffer(Pos+1); //addr of pstr is 0x0004bad4
memcpy( pstr,dataBuff,Pos); //value of pstr is "??????..."
tmpStr.ReleaseBuffer();
0
 
jkrCommented:
I usually don't repeat myself, but CString DOES have means to extract data without usind any temporary storage - 'Left()','Mid()' and 'Right()'. So,

CString strData;
CString str1;
CString str2;

str1 = strData.Mid ( 0, 10);
str2 = strData.Mid ( 11, 20);

should definitely work, even on CE...
0
 
AxterCommented:
Correction:
char* dataBuff[1024];
loadDataIntoBuffer(dataBuff); //dataBuff has data

DWORD Pos = 10;

CString tmpStr = "";
LPTSTR pstr = tmpStr.GetBuffer(Pos+1);
memcpy(pstr,dataBuff,Pos);
pstr[Pos]=0;
tmpStr.ReleaseBuffer();
0
 
jkrCommented:
Again: There is no need to use any temproary storage...

BTW:

>>char* dataBuff[1024];

Why would we need 1024 'char*'? :o)

0
 
AxterCommented:
Actually, in reading the documentation for CString::GetBuffer, the Length argument doesn't include the NULL terminator.

I would still try adding an extra byte to GetBuffer, just to make sure the CE version is not incorrectly implemented.
0
 
AxterCommented:
el_rooky,
Is the data you're adding to your CString object, of wide charactor type?

CString is a wide charactor type in Windows CE.
This could be what's causing your problem.
0
 
AxterCommented:
>>Why would we need 1024 'char*'? :o)
Very good point.

el_rooky,
How is loadDataIntoBuffer putting data into dataBuff?

Can you post the type for loadDataIntoBuffer?

I think your real problem is the declaration of dataBuff.

It should one of the following, and not both:
char dataBuff[1024];

or

char* dataBuff;

Depending on what loadDataIntoBuffer receives for an argument.

I suspected it should be char dataBuff[1024];
0
 
jkrCommented:
Well, as it seems to be en vogue now not to care what others post, I'll also follow that scheme:

CString has methods to extract data without usind any temporary storage - 'Left()','Mid()' and 'Right()'. So, just use

CString strData;
CString str1;
CString str2;

str1 = strData.Mid ( 0, 10);
str2 = strData.Mid ( 11, 20);
0
 
AxterCommented:
jkr,
The method you're posting only works if you first get the data into strData.
IMHO, The questioner seems to be having problems getting to that point.
0
 
el_rookyAuthor Commented:
I just came back from lunch and found all these comments, it's great! I've tried most of your suggestions and here are my findings:

1) jkr - my data buffer is actually of size 49152 wich in windows CE is consider a large buffer. And I don't want to convert it to a CString, otherwise your suggestion makes all the sence.

2) Axter - I've tried all modifications suggested to the current code and nothing works. Except when I use TCHAR instead of char. So you are right. Windows CE is a unicode enviroment.

3) The question still is, since I can not chance the dataBuff to a wide character type (dont ask me why, there are a lot of reasons. DataBuff must remain as an array of chars) how do I copy string of characters from an array of chars into a CString?
0
 
AxterCommented:
You need to first convert the data to wide charactor, and then put it into the CString buffer.
0
 
AxterCommented:
If your source data is of char* type, you have no choice but to first convert the data, before memcpy to the CString buffer.

As I stated previously, Windows CE uses Wide charactor type for CString, so any data you put into the CString buffer, has to be of Wide charactor type, in order for it to be readable.
0
 
jkrCommented:
OK, sorry, it seems that I misread the Q (blushing :o)

So, let's see:

char dataBuff[1024];
CString str1;
CString str2;

wchar_t* pwsz = str1.GetBufferSetLength ( 11);

ZeroMemory ( pwsz, 11 * sizeof ( wchar_t));

wcscpyn ( pwsz, ( wchar_t*) dataBuff);

wchar_t* pwsz = str1.GetBufferSetLength ( 11);

ZeroMemory ( pwsz, 11 * sizeof ( wchar_t), 10);

wcscpyn ( pwsz, ( wchar_t*) dataBuff + 11, 10);
0
 
el_rookyAuthor Commented:
jkr,
following your example the following piece of code does not work either:

char dataBuff[18] = "abcdefghijklmnopq";
CString tmpStr = "";

wchar_t* pwsz = tmpStr.GetBufferSetLength (5);
ZeroMemory ( pwsz, 5 * sizeof ( wchar_t));
wcscpy ( pwsz, ( wchar_t*) dataBuff);

pwsz gets a bunch of '?'

notice that I've changed wcspyn to wcspy since wcspyn was undefined.

0
 
el_rookyAuthor Commented:
jkr,
following your example the following piece of code does not work either:

char dataBuff[18] = "abcdefghijklmnopq";
CString tmpStr = "";

wchar_t* pwsz = tmpStr.GetBufferSetLength (5);
ZeroMemory ( pwsz, 5 * sizeof ( wchar_t));
wcscpy ( pwsz, ( wchar_t*) dataBuff);

pwsz gets a bunch of '?'

notice that I've changed wcspyn to wcspy since wcspyn was undefined.

0
 
AxterCommented:
Try this:

void SimpleCharToWide(const char* Src, int Len, wchar_t* Target)
{
     for(int i = 0;i < Len;++i)
     {
          Target[i] = Src[0];
          Target[i+1] = 0;
     }
}

void Functionx(void)
{
     char dataBuff[] = "abcdefghijklmnopq";

     DWORD Pos = 10;

     CString tmpStr = "";
     wchar_t* pwsz = tmpStr.GetBufferSetLength ((Pos+1)*sizeof(wchar_t));
     SimpleCharToWide(dataBuff, strlen(dataBuff), pwsz);
     tmpStr.ReleaseBuffer();
}
0
 
AxterCommented:
There is an API function that you should use in place of the SimpleCharToWide function I posted, but I don't remember what it's called.
0
 
AxterCommented:
You should use MultiByteToWideChar function to convert your char data to widechar data.
0
 
jkrCommented:
>>pwsz gets a bunch of '?'

Yes, it should have read

wchar_t* pwsz = tmpStr.GetBufferSetLength (6); // 6, as we need a trailing zero!
ZeroMemory ( pwsz, 6 * sizeof ( wchar_t));
memcpy ( pwsz, ( wchar_t*) dataBuff, 5 * sizeof ( wchar_t));
0
 
AxterCommented:
Here's an example using MultiByteToWideChar

void Function(void)
{
     char dataBuff[] = "abcdefghijklmnopq";

     DWORD Pos = 10;

     CString tmpStr = "";
     wchar_t* pwsz = tmpStr.GetBufferSetLength ((Pos+1)*sizeof(wchar_t));
     MultiByteToWideChar(CP_ACP, 0, dataBuff, strlen(dataBuff), pwsz, strlen(dataBuff));
     tmpStr.ReleaseBuffer();
}

0
 
AxterCommented:
Correction:
void Function(void)
{
    char dataBuff[] = "abcdefghijklmnopq";

    DWORD Pos = 10;

    CString tmpStr = "";
    wchar_t* pwsz = tmpStr.GetBufferSetLength ((Pos+1)*sizeof(wchar_t));
    MultiByteToWideChar(CP_ACP, 0, dataBuff, strlen(dataBuff), pwsz, (Pos+1)*sizeof(wchar_t));
    tmpStr.ReleaseBuffer();
}
0
 
jkrCommented:
Hum, I am confused now - I thought we were dealing with the UNICODE version of CString?
0
 
AxterCommented:
>>Hum, I am confused now - I thought we were dealing with
>>the UNICODE version of CString?

Yes, but the source data is char type.
So he's trying to put char type data into a UNICODE CString object.
0
 
AxterCommented:
FYI:
MultiByteToWideChar is used to convert ANSI char type data to wide char.
It can also convert MultiByte to wide char, as the name suggest.
0
 
jkrCommented:
>>Yes, but the source data is char type.

Argl, I though it was UNICODE "disguised" in a char buffer...
0
 
el_rookyAuthor Commented:
sorry for the confusion jkr. Thanks for your help anyways. I've posted the same question in the Windows CE group. IF you go there I'll give you those points.

Axter,
your function SimpleCharToWide works better than the MultiByteToWideChar function, which does not always gives me the correct string lenght. Your piece of code works great for me with a fix to a couple of bugs.

void SimpleCharToWide(const char* Src, int Len, wchar_t* Target)
{
    for(int i = 0;i < Len;++i)
    {
         Target[i] = Src[i]; //bug1 Src[0];
         Target[i+1] = 0;
    }
}

void Functionx(void)
{
    char dataBuff[] = "abcdefghijklmnopq";

    DWORD Pos = 10;

    CString tmpStr = "";
    wchar_t* pwsz = tmpStr.GetBufferSetLength ((Pos+1)*sizeof(wchar_t));
//    SimpleCharToWide(dataBuff, strlen(dataBuff), pwsz);
    SimpleCharToWide(dataBuff, pos, pwsz);
    tmpStr.ReleaseBuffer();
}
0
 
el_rookyAuthor Commented:
sorry for the confusion jkr. Thanks for your help anyways. I've posted the same question in the Windows CE group. IF you go there I'll give you those points.

Axter,
your function SimpleCharToWide works better than the MultiByteToWideChar function, which does not always gives me the correct string lenght. Your piece of code works great for me with a fix to a couple of bugs.

void SimpleCharToWide(const char* Src, int Len, wchar_t* Target)
{
    for(int i = 0;i < Len;++i)
    {
         Target[i] = Src[i]; //bug1 Src[0];
         Target[i+1] = 0;
    }
}

void Functionx(void)
{
    char dataBuff[] = "abcdefghijklmnopq";

    DWORD Pos = 10;

    CString tmpStr = "";
    wchar_t* pwsz = tmpStr.GetBufferSetLength ((Pos+1)*sizeof(wchar_t));
//    SimpleCharToWide(dataBuff, strlen(dataBuff), pwsz);
    SimpleCharToWide(dataBuff, pos, pwsz);
    tmpStr.ReleaseBuffer();
}
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 17
  • 8
  • 7
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now