|
agreed.
Maximilien Lincourt
"Never underestimate the bandwidth of a station wagon filled with backup tapes." ("Computer Networks" by Andrew S Tannenbaum )
|
|
|
|
|
I've got code that calls this method on an open file. GetFilePath() returns the string as expected, but it sets the last error to 87 (Invalid parameter). It seems to only be happening in a release build with an open file on a CD (read-only).
Does this make sense to anyone?
J
"I am the Lorax. I speak for the trees."
|
|
|
|
|
How are you verifying this error is being set?
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
I inserted GetLastError() calls before and after the GetFilePath() call. Then I traced it.
J
"I am the Lorax. I speak for the trees."
|
|
|
|
|
Like this?
int x = GetLastError();<br />
CString str;<br />
str = file.GetFilePath();<br />
x = GetLastError();
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Yup. And I traced into the MFC code, but of course I can't add that code around the 3 or 4 API calls below CFile::GetFilePath().
J
"I am the Lorax. I speak for the trees."
|
|
|
|
|
Strange, as I see no calls to SetLastError() in filest.cpp. And for GetFilePath() to return data whilst also setting the error value is odd. Usually when a functions sets an error, no useable data is returned.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
DavidCrow wrote:
Strange, as I see no calls to SetLastError() in filest.cpp.
Well, GetFilePath() makes several API calls. These typically return a value indicating an error has occurred and set the last error value.
DavidCrow wrote:
And for GetFilePath() to return data whilst also setting the error value is odd.
Hence my confusion.
DavidCrow wrote:
Usually when a functions sets an error, no useable data is returned.
There are no documented error conditions in CFile::GetFilePath(). According to MSDN it shouldn't even throw any exceptions, although the example wraps the call in a try/catch block.
My code throws no exception. We only found the problem because a GetLastError() call later in the process was giving the error code when the API call legitimately didn't fail.
J
"I am the Lorax. I speak for the trees."
|
|
|
|
|
Jamie Hale wrote:
...a GetLastError() call later in the process was giving the error code...
So could SetLastError() be getting called long after GetFilePath() has come and gone?
For example, I've see instances of this type of code:
MyLoggingFunction("%d\n", SomeFunction());
DWORD dw = GetLastError();
One of two things can happen here. SomeFunction() could internally call SetLastError(0) but the above call to GetLastError() could be non-zero if MyLoggingFunction() called SetLastError() . Or, SomeFunction() could call SetLastError() with a non-zero value, but by the time MyLoggingFunction() had finished, GetLastError() is 0. Make sense?
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Makes perfect sense. But I was tracing through the code in the debugger. The code looked like this...
DWORD dwErr = GetLastError();
CString strFilename = f.GetFilePath();
dwErr = GetLastError();
It boggles the mind. I have a feeling it could be because the filenames were originally very long, and to write them to a CD the filenames get truncated. The filesystem on the CD could be wackified somehow. But I'm grasping at straws here.
J
"I am the Lorax. I speak for the trees."
|
|
|
|
|
Try this:
DWORD dwErr = GetLastError();
char s[256];
lstrcpy(s, f.GetFilePath());
dwErr = GetLastError();
CString strFilename = s;
dwErr = GetLastError();
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
?? Implying that the SetLastError() might be called in CString::operator=()?
J
"I am the Lorax. I speak for the trees."
|
|
|
|
|
Yes.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Have you tried rebuilding your release version with Debug information and stepping into the MFC code to see which API is failing?
Another option is to copy the CFile::GetStatus into your own code (temporarily), sprinkle that with diagnostic code, and then call it instead of GetFilePath.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
Alvaro Mendez wrote:
Another option is to copy the CFile::GetStatus into your own code (temporarily), sprinkle that with diagnostic code, and then call it instead of GetFilePath.
That's probably the best way to handle it.
The way not to handle it is by forcefully clearing the error after the call. Which is what I've done.
J
"I am the Lorax. I speak for the trees."
|
|
|
|
|
Hi All.
I am after some code samples/info about controlling a device via the com port using C++/MFC (though I have never used it). Any info/articles/links appreciated.
Specifically, would like to set up the com port (9600 baud, 8, None, 1) and send and recieve text strings (Hyperterminal Style).
Cheers
If sex is a pain in the ass, then you are doing it wrong!
|
|
|
|
|
Hello
Here is the way how i did it.
Create a ActiveX Contrl-->Microsoft Communication Control32.
and add a member Variable for it.
Create a OnComm Event with the Wizard.
Open the Port with:
m_MSComm is the member variable for the Active X Control
m_MSComm.SetCommPort(1);<br />
m_MSComm.SetSettings(9600,N,8,1);
m_MSComm.SetInputLen(1);<br />
m_MSComm.SetRThreshold(1);<br />
m_MSComm.SetDTREnable(false);<br />
m_MSComm.SetRTSEnable(false);<br />
m_MSComm.SetPortOpen(true);
Close the Port:
m_MSComm.SetPortOpen(false);
Send a Byte
<br />
m_MSComm.SetRTSEnable(true);<br />
CString str; <br />
str=
vVar.vt = VT_BSTR;<br />
vVar.bstrVal=str.AllocSysString();<br />
m_MSComm.SetOutput(vVar);<br />
SysFreeString(vVar.bstrVal);<br />
m_MSComm.SetRTSEnable(false);<br />
Recieve something:
<br />
BEGIN_EVENTSINK_MAP(CMainDlg, CDialog)<br />
ON_EVENT(CMainDlg, IDC_MSCOMM, 1 , OnMscomm, VTS_NONE)<br />
END_EVENTSINK_MAP()<br />
<br />
<br />
void CMainDlg::OnMscomm() <br />
{<br />
switch(m_MSComm.GetCommEvent())<br />
{<br />
case 2:
CString Empf=m_MSComm.GetInput());<br />
break;<br />
} <br />
<br />
}<br />
That should it be.
Mfg DarkMarine.
DarkMarine@aon.at
|
|
|
|
|
Superb Stuff: Looks like I will be dragged (Kicking and Screming) into MFC.
Thankyou.
Were is .at at ? (Atlantis, Austria, Antartica) ?
If sex is a pain in the ass, then you are doing it wrong!
|
|
|
|
|
Glad that i could help you.
and .at is Austria.
Mfg DarkMarine
|
|
|
|
|
I have a method which calls the methods from lib.
In one of lib methods there is an exception.
How can I catch it.
:: MyFunc ()
{
try
{
}
catch (CException * ex)
{
ex-> Delete ()
}
}
Best regards,
Eugene Pustovoyt
|
|
|
|
|
To catch an exception, it first has to be thrown? Is the method in the lib (the dll actually) throwing an exception?
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
I call a lib method with incorrect parameter. Thus there is an exception which I cannot catch.
Best regards,
Eugene Pustovoyt
|
|
|
|
|
So is the lib method actually throwing the exception?
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Like David points out verify the lib method is explicitly throwing the exception. In other words, it needs to have a line similar to this:
throw new CSomeException(...);
Also,
- Verify that the exception being thrown is derived from CException.
- Verify that the exception is thrown by pointer, not by value.
If the exception is not explicitly being thrown, then most likely there's a bug in the code which is causing the program to throw an Access Violation exception. Those you can't catch like you're trying to do. The easiest way is by adding a catch-all clause:
catch (CException* e)
{
...
}
catch (...)
{
}
There are other ways to explicitly catch these type of exceptions (do a search for structured exception handling, if you're interested) but I recommend you take the simple route I explained above and clean up your code.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
If all else fails, use the following to catch all exceptions:
try
{
//somecode
{
catch (...)//note the dots, these are important
{
//cleanup
}
Joel Lucsy
|
|
|
|