|
Hello people!
I have the following (simplified) code:
OVERLAPPED Overlap = {0};
Overlap.hEvent = event_reader_with_CreateEvent;
if (ReadFile(handle_for_com_port, pBuffer, buffer_size, &bytes_read, &Overlap)) ...data read, go on happily...
else if (GetLastError() == ERROR_IO_PENDING)
{
if (WaitForMultipleObjects(1, &Overlap.hEvent, FALSE, dwTimeOut) == WAIT_OBJECT_0)
{
if (GetOverlappedResult(handle_for_com_port, &Overlap, &bytes_read, FALSE)) ...data read, go on happily ...
else if (GetLastError() == ERROR_IO_INCOMPLETE)
{
What to do here???
} else ...IO error, report and go on not so happily...
}
}
So what to do in case of ERROR_IO_INCOMPLETE? Googling around i found code sniplts where they simply try GetOverlappedResult again and again for a while until it succeeds OR some timeout or somesuch occurs. However, time to time i run into the following confusing situation:
1. ReadFile called resulting in ERROR_IO_PENDING
2. Waiting on the event returns with WAIT_OBJECT_0, the event is signalled
3. GetOverlappedResult returns FALSE and the last error code is ERROR_IO_INCOMPLETE, however, if i check the buffer (pBuffer) with the debugger i see that the data is already fully in it, however, bytes_read is 0 and it remains zero and repeatedly calling GetOverlappedResult will always result in ERROR_IO_INCOMPLETE for all ethernity (or at least as long as i was willing to wait).
Anyone knows why this is happening and what i can do to solve it? Another thing that turned up is that if i try to "timeout" from this, i mean, call GetOverlappedResult a few times giving up after a while and continuing will result in "damaged memory block", maybe because the buffer pointed at pBuffer goes out of scope but someone, somewhere still tries to write into it (just a guess)? Anyways, timeouting still can't be a solution because i lose the data that was actually read into the buffer, confusing confusing confusing...help!!!
p.s: if i call GetOverlappedResult with TRUE as the last parameter than it just seem to hang...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Leela: Fry, you're wasting your life sitting in front of that TV. You need to get out and see the real world.
Fry: But this is HDTV. It's got better resolution than the real world <
modified on Monday, November 8, 2010 3:13 PM
|
|
|
|
|
|
Thank you for the link but i did set up the port using the DCB structure, SetCommState and SetCommTimeouts.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Leela: Fry, you're wasting your life sitting in front of that TV. You need to get out and see the real world.
Fry: But this is HDTV. It's got better resolution than the real world <
|
|
|
|
|
That's strange.
Could you try giving TRUE for the third parameter of WaitForMultipleObjects or use WaitForSingleObject !!!
|
|
|
|
|
In the actual code there are more then one event i am waiting for that is why you see WaitForMultipleObjects , i just simplified the code for simplicity. And yes, i am sure that the event signalling the overlapped operation completion is fired, it is the very first event handle inside the array passed to the wait function and i get WAIT_OBJECT_0 from it. Most of the time this seems to be working ok but time to time...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Leela: Fry, you're wasting your life sitting in front of that TV. You need to get out and see the real world.
Fry: But this is HDTV. It's got better resolution than the real world <
|
|
|
|
|
Oh... I've so forgotten the usage of character arrays!
for example:
char * Func (char * sT)
{
char sRet [MAX_STR_SIZE] = "";
strcpy (sRet, sT);
return sRet;
}
And when compiling I get a warning returning address of local variable or temporary
I think I know why it tells me this, but not completely sure... Would it be more reasonable to do void Func (char * sT, char * sRet) ?
|
|
|
|
|
You should really stop home cooked memory handling and write std::string sRet(sT) , or (MFC) CString sRet(sT) , or ATL::CString sRet(sT) ... other string classes omitted.
cheers,
AR
When the wise (person) points at the moon the fool looks at the finger (Chinese proverb)
|
|
|
|
|
Err... well, I know that and agree with you, but my boss does not think the same. I have mentioned him several times that it is more secure to use std::string or any other, but apparently it is best to use char * and home cooked functions for the system the application will run in.
I understand your worries, I will make sure someone checks my code before it goes on the system.
|
|
|
|
|
piul wrote: my boss does not think the same. I have mentioned him several times that it is more secure to use std::string or any other, but apparently it is best to use char * and home cooked functions for the system the application will run in. I sympathize Try find another job or another boss
Meanwhile: piul wrote:
char * Func (char * sT)
{
char sRet [MAX_STR_SIZE] = "";
strcpy (sRet, sT);
return sRet;
} And when compiling I get a warning returning address of local variable or temporary
Your nice compiler warns you that sRet points to deallocated memory when returned.
A solution is to make sRet static: static char sRet [MAX_STR_SIZE] = {0}; .
It will be overwritten on each call but valid on return.
For safety use strncpy(sRet, sT, MAX_STR_SIZE - 1) .
cheers,
AR
When the wise (person) points at the moon the fool looks at the finger (Chinese proverb)
|
|
|
|
|
You have a buffer that is local - it exists on the stack.
When you exit the routine the stack, for that routine, will no longer exist.
As for the best way to do it it depends on what you are doing. But at a minimum the calling routine would need to pass its local buffer for the copy operation. Or manage it on the heap and make sure to delete it when done.
|
|
|
|
|
piul wrote: I think I know why it tells me this, but not completely sure...
Because sRet ceases to exist once Func() goes out of scope.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
The problem is that you are returning a pointer to a buffer that will go out of scope after your function exit: then then returned pointer is no longer valid and what you find there is going to be pseudo-random.
To fix the problem you can:
- allocate the output buffer out from the function
- allocate the output buffer using
new or malloc (but you should remember to deallocate it when it is no more needed)
However, as Alan said, the very best way is to stop using C-style strings and use std::string instead: the STL is one of the better solutions because all its classes are inlined and highly optimized. This will give you very good performances with a minimal footprint (the unused classes and methods simply are not compiled and don't affect the executable size).
|
|
|
|
|
You should look up to the signature of strcpy as a reference.
The first parameter to strcpy is the out parameter and the second is the in parameter.
So change your function to be something similar even though it really doesn't make sense in this context -
int Func(char* sRet, const char* sT)
{
return strcpy(sRet, sT);
}
Also, if you're not able to use std::string , at least use the secure versions of the C runtime functions like strcpy_s .
|
|
|
|
|
sRet is a local variable allocated on the stack and as such the memory it uses will be reclaimed when Func returns. That means the stuff it points to will probably not contain what you think it does at some point in the future.
So you have essentially 2 choices:
1. Use void Func (char * sT, char * sRet) as you suggest. Func would then copy the string into the memory supplied by the caller. That memory of course has its own lifecycle.
2. Allocate memory in Func(). For example in C++:
char * Func (char * sT)
{
char * sRet = NULL;
sRet = new char[MAX_STR_SIZE];
if (sRet)
strcpy (sRet, sT);
return sRet;
}
In this case someone has to deallocate the newed up memory later. So for example:
void Foo(void)
{
char *mystr = Func("test");
DoSomethingInteresting(mystr);
delete mystr [];
}
|
|
|
|
|
Hi,
I've created a dialog box from within the activex control and it contained a edit control.
But that edit control doesn't accept text when it is displayed..What might be the prob?
|
|
|
|
|
lakshman rao wrote: But that edit control doesn't accept text...
You can't type into it? You can't paste into it? You can't set its text via code?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
DavidCrow wrote: You can't type into it? You can't paste into it? You can't set its text via code?
I can't type into it.
|
|
|
|
|
Has it been disabled or set to read-only?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
DavidCrow wrote: Has it been disabled or set to read-only?
Nope, both properties are set to false
|
|
|
|
|
does anybody know reason fot this?
|
|
|
|
|
Can sb. translate following code to C# pls:
<br />
<br />
<br />
INT32U UuDecodeLength(INT32U nSrcLen)<br />
{<br />
INT32U uDestLen;<br />
uDestLen = (nSrcLen * 3) / 4;<br />
return uDestLen;<br />
}<br />
<br />
<br />
INT32U UuEncodeLength(INT32U nSrcLen)<br />
{<br />
INT32U uDestLen;<br />
uDestLen = (nSrcLen * 4) / 3;<br />
if ( ((nSrcLen * 4) % 3) != 0 )<br />
{
uDestLen++;<br />
}<br />
return uDestLen;<br />
}<br />
<br />
<br />
<br />
INT32U UuDecode(INT8U* pDst,const INT8U* pSrc,INT32U nSrcLen)<br />
{<br />
unsigned int nDstIndex;<br />
unsigned int nSrcIndex;<br />
nDstIndex = 0;<br />
nSrcIndex = 0;<br />
while(nSrcIndex < nSrcLen)<br />
{<br />
pDst[nDstIndex] = ((pSrc[nSrcIndex++] - 0x20) << 2 ) & 0xFC;
pDst[nDstIndex++] |= ((pSrc[nSrcIndex] - 0x20) >> 4 ) & 0x03;
if ( (nSrcIndex + 1) >= nSrcLen )<br />
{
break;<br />
}<br />
pDst[nDstIndex] = ((pSrc[nSrcIndex++] - 0x20) << 4 ) & 0xF0;
pDst[nDstIndex++] |= ((pSrc[nSrcIndex] - 0x20) >> 2 ) & 0x0F;
if ( (nSrcIndex + 1) >= nSrcLen )<br />
{
break;<br />
}<br />
pDst[nDstIndex] = ((pSrc[nSrcIndex++] - 0x20) << 6 ) & 0xC0;
pDst[nDstIndex++] |= ((pSrc[nSrcIndex] - 0x20) ) & 0x3F;
nSrcIndex++;<br />
}<br />
return nDstIndex;<br />
}<br />
<br />
<br />
<br />
INT32U UuEncode(INT8U* pDst,const INT8U* pSrc,INT32U nSrcLen)<br />
{<br />
unsigned int nDstIndex;<br />
unsigned int nSrcIndex;<br />
nDstIndex = 0;<br />
nSrcIndex = 0;<br />
while(nSrcIndex < nSrcLen)<br />
{<br />
pDst[nDstIndex++] = ((pSrc[nSrcIndex] >> 2) & 0x3F) + 0x20;<br />
pDst[nDstIndex] = (pSrc[nSrcIndex++] << 4) & 0x3F;<br />
if ( nSrcIndex >= nSrcLen )<br />
{
pDst[nDstIndex] += 0x20;<br />
nDstIndex++;<br />
break;<br />
}<br />
pDst[nDstIndex] |= (pSrc[nSrcIndex] >> 4) & 0x3F;<br />
pDst[nDstIndex++] += 0x20;<br />
pDst[nDstIndex] = (pSrc[nSrcIndex++] << 2) & 0x3F;<br />
if ( nSrcIndex >= nSrcLen )<br />
{
pDst[nDstIndex] += 0x20;<br />
nDstIndex++;<br />
break;<br />
}<br />
pDst[nDstIndex] |= (pSrc[nSrcIndex] >> 6) & 0x3F;<br />
pDst[nDstIndex++] += 0x20;<br />
pDst[nDstIndex] = (pSrc[nSrcIndex++] & 0x3F) + 0x20;<br />
nDstIndex++;<br />
}<br />
return nDstIndex;<br />
}<br />
|
|
|
|
|
No! No one will do your job for you! Please make an effort and came back with questions about specific issues, showing what have you already done, explaining why it doesn't work as you expected and possibly adding a code snippet of the relevant code!
|
|
|
|
|
ok I've made the job only just...
but can somebody explain to me the UU-Encoding,
because i.e. the UuEncode method returns an unsigned integer.
I thought UU-Encoding converts Unicode to ASCII.
So what should I do with this "uint"?
The method "UuEncodeLength" returns me the same length...
So I don't see there any differences in their functions...
|
|
|
|
|
djfresh wrote: The method "UuEncodeLength" returns me the same length...
This is not true; look at its code:
INT32U UuEncodeLength(INT32U nSrcLen)
{
INT32U uDestLen;
uDestLen = (nSrcLen * 4) / 3;
if ( ((nSrcLen * 4) % 3) != 0 )
{ uDestLen++;
}
return uDestLen;
}
Now let's look at what happen:
- if
nSrcLen = 1 then the function returns 2; - if
nSrcLen = 2 then the function returns 3; - if
nSrcLen = 3 then the function returns 4; - if
nSrcLen = 4 then the function returns 6; - and so on...
|
|
|
|
|
sorry my english is not so good...
I've meant that the methods UuEncodeLength and UuEncode are returning the same value...
i.e. if you enter 2 characters they both returns 3.
Example:
12 returns 3...
but real UUencoding must return:
,3(@
|
|
|
|