|
Thanks for the suggestions! However, this piece of code is causing me to get the error, "A nonstatic member reference must be relative to a specific object". I tried to use this-> before m_pEventStopRequested->m_hObject but it did not solve the problem. I have the declaration for the CEvent in the constructor, but I am not sure to what object it is referring.
if (WaitForSingleObject(m_pEventStopRequested->m_hObject, 0U) == WAIT_OBJECT_0)
{
m_pEventThreadDone.SetEvent();
return;
}
Would you happen to know what object it is referring to?
|
|
|
|
|
AndrewG1231 wrote: However, this piece of code is causing me to get the error, "A nonstatic member reference must be relative to a specific object". What is the exact error number?
AndrewG1231 wrote: m_pEventThreadDone.SetEvent(); Should be:
m_pEventThreadDone->SetEvent(); That, and adding a return value, is all I had to do to get the code to compile.
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Here is the exact compiler message of the error.
Dlg_SpectrumAnalyzer.cpp(150): error C2227: left of '->m_hObject' must point to class/struct/union/generic type
1>Dlg_SpectrumAnalyzer.cpp(153): error C2227: left of '->SetEvent' must point to class/struct/union/generic type
1>Dlg_SpectrumAnalyzer.cpp(154): error C2561: 'CDlg_SpectrumAnalyzer::Acq_Data' : function must return a value
However, I implemented you suggestion a bit differently. I did not use void Acq_DAta(void) instead I have incorporated everything in the following member.
UINT CDlg_SpectrumAnalyzer::Acq_Data(LPVOID pParam)
{
CDlg_SpectrumAnalyzer *dlg =(CDlg_SpectrumAnalyzer*) pParam;
HWND hdlg = dlg->GetSafeHwnd();
while(1)
{
if (WaitForSingleObject(m_pEventStopRequested->m_hObject, 0U) == WAIT_OBJECT_0)
{
m_pEventThreadDone->SetEvent();
return;
}
else
{
dlg->m_inst->ADCdbRead(dlg->m_AcqChan,dlg->m_MaxFreq*2,dlg->m_BuffSize,dlg->m_fulldata,dlg->m_halfdata);
while(dlg->m_Continue && ! dlg->m_inst->m_Flags.Halt)
dlg->m_inst->ADCdbInquire(dlg- >m_halfdata,hdlg,MSG_DRAW_SPECTRUM);
dlg->m_inst->ADCdbStop();
dlg->m_inst->EndOperation();
return 1;
}
}
} Here is the button control code.
void CDlg_SpectrumAnalyzer::OnBnClickedRun()
{
if (WaitForSingleObject(m_pEventThreadDone->m_hObject, 0U) == WAIT_OBJECT_0)
{
m_pEventStopRequested->ResetEvent();
m_pEventThreadDone->ResetEvent();
m_pThread = AfxBeginThread(Acq_Data, this, THREAD_PRIORITY_HIGHEST);
}
} Have I done something foolish in the way I was trying to use your suggestion?
modified 13-Sep-12 13:54pm.
|
|
|
|
|
AndrewG1231 wrote:
Have I done something foolish in the way I was trying to use your suggestion? Yes, you are trying to access non-static members from within a static function. Check my code again. Note there are two Acq_Data() functions.
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
So, I saw the two Acq_Data() functions and I ran into the following problem with the use of the dlg pointer and the hdlg entry in the ADCdbInquire(...) member which is of the type HWND .
dlg->m_inst->ADCdbRead(dlg->m_AcqChan,dlg->m_MaxFreq*2,dlg->m_BuffSize,dlg->m_fulldata,dlg->m_halfdata);
while(dlg->m_Continue && ! dlg->m_inst->m_Flags.Halt)
dlg->m_inst->ADCdbInquire(dlg->m_halfdata,hdlg,MSG_DRAW_SPECTRUM);
dlg->m_inst->ADCdbStop();
dlg->m_inst->EndOperation();
I tried to combine the call to function and the actual code to enable the process, apparently, this leads to the compiler issue. How can I get the handle? I did try just using HWND hdlg = GetSafeHwnd(); and eliminating all the dlg code which compiled fine but led to the following runtime error.
Unhandled exception at 0x012d2ba9 in WinSTM.exe: 0xC0000005: Access violation reading location 0x000002af.
Your patience has been amazing..usually by now I have received some type of comment about my newbie-ness. Thanks!
|
|
|
|
|
AndrewG1231 wrote: ...I ran into the following problem with the use of the dlg pointer... From whence comes the dlg pointer?
AndrewG1231 wrote: which compiled fine but led to the following runtime error.
Unhandled exception at 0x012d2ba9 in WinSTM.exe: 0xC0000005: Access violation reading location 0x000002af. Sounds like a NULL pointer. Use the debugger, set a breakpoint on the call to ADCdbRead() , and check the values of dlg , m_inst , and m_Flags .
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Hey, it has been a little while, but your suggestions were very helpful in diagnosing my problem. I am currently working on a solution, but wanted to share my thanks.
|
|
|
|
|
Glad you're progressing.
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Actually, SendMessage is synchronous... so if it's threaded, it really should be a PostMessage , otherwise you'll tie up the worker thread waiting on the GUI update.
|
|
|
|
|
I m reading some data from device whose length I dont know at compile so I made a structure as of following type to store data
struct MessagData
{
DWORD dwSize;
BYTE byData[1];
}
(as far as I know byData[1] declares a byte array of variable length, but I dont know where it allocates memory for the same)
and I m taking a pointer to a variable of this type structure as shown below
MessagData* pMessagData = new MessagData;
suppose data read from device is stored in some variable mentioned below:
char chReadData[100];
after filling the read data which is of variable length i am copying the same data to byData variable of this pointer as shown below:
memcpy(pMessagDat->byData,
chReadData,
pMessagDat->dwSize);
[Length of read data is always less than 100]
upto here it is working fine but when i am trying to do following thing application gave some error of heap corruption even though i m deallocating in the same application in which i have created it.
Please someone help me......
|
|
|
|
|
Rahul from Poona wrote: as far as I know byData[1] declares a byte array of variable length
BYTE byData[1]; declares an array of BYTEs, of length 1.
C/C++ does not have variable length arrays.
|
|
|
|
|
Chris Losinger wrote: C/C++ does not have variable length arrays.
However that type of structure is a very common idiom in C and probably in C++ in certainly situations.
And in common usage the array size would be determined at run time - thus dynamic by most definitions.
|
|
|
|
|
jschell wrote:
And in common usage the array size would be determined at run time - thus dynamic by most definitions.
well, it would be malloc'd by the programmer. that's not really a dynamic array, that's just malloc.
|
|
|
|
|
Chris Losinger wrote: that's not really a dynamic array, that's just malloc.
No idea what that is supposed to mean.
Perhaps you are referring to a C++ array that sizes itself (at least conceptually) according to the data in it. And of course it does that by dynamically, rather than statically, allocating memory.
|
|
|
|
|
i'm saying that silly array-of-one hack doesn't do it for you. there's nothing 'dynamic' about the array of one. you still have to go and malloc the memory explicitly.
|
|
|
|
|
|
guess what, words have synonyms.
you know, like when you started using the word "dynamic" to describe what i and the OP were calling "variable length"
|
|
|
|
|
Chris Losinger wrote: guess what, words have synonyms.
Guess what... I said "thus dynamic by most definitions".
Chris Losinger wrote: you know, like when you started using the word "dynamic" to describe what i and
the OP were calling "variable length"
My usage of that word is a commonly known term for that. As the links that I posted demonstrate.
|
|
|
|
|
you changed the subject. i didn't follow your lead. hence your confusion.
|
|
|
|
|
Chris Losinger wrote: you changed the subject. i didn't follow your lead. hence your confusion.
No confusion on my part.
My first post was in response to your post in which you implicitly suggested that it wasn't possible to create an array in C/C++ at run time.
And then you decided to apply a non-standard definition to the word "dynamic".
|
|
|
|
|
Calling it an idiom may be misleading - it may be commonly used, but it is most certainly not a recommended practice, and technically not even supported by the standard. Moreover, while it probably works (depending on the strictness of the compiler) in C++, there are much better ways to create dynamic arrays. In fact you have to look no further than std::vector .
In any case, you have to be very careful about allocating and deallocating your structs in exactly the right way. In C++ you could write your own constructor and destructor, but in C it's easy to mess it up, and the compiler won't notice because you actively worked around it.
P.S.: you can certainly use that construct dynamically, but it's also possible to define an instance of that type on the stack instead if you know the required size at compile time. All you need is a sufficiently large char array, and then assign your struct pointer to the start of that array.
|
|
|
|
|
Stefan_Lang wrote: Calling it an idiom may be misleading - it may be commonly used, but it is most
certainly not a recommended practice, and technically not even supported by the
standard.
First part is an opinion but feel free to substantiate it.
Second part there is nothing in ANSI C prior to C99 that disallows it, and except for unusual uses is in specifically defined. And more than that C99 specifically allows for 'flexible array structure' to explicitly define the behavior. See the following link and search for 'flexible' (and note that that that compiler actually extends the support for the type.)
http://pic.dhe.ibm.com/infocenter/lnxpcomp/v121v141/index.jsp?topic=%2Fcom.ibm.xlcpp121.linux.doc%2Flanguage_ref%2Fstrct.html[^]
Stefan_Lang wrote: in C++, there are much better ways to create dynamic arrays. In fact you have
to look no further than std::vector .
Yep - in C++. But not in C.
Stefan_Lang wrote: In any case, you have to be very careful about allocating and deallocating
Yes. Just as you must be careful about anything involving pointers and memory in C/C++. But that doesn't have anything to do with what I said.
Stefan_Lang wrote: but it's also possible to define an instance of that type on the stack instead
if you know the required size at compile time.
Except that is exactly the point - it isn't known at compile time. And moreover, if it was known at compile time they you could create it dynamically as well.
So what does any of that have to do with creating it dynamically or on the stack?
|
|
|
|
|
jschell wrote: First part is an opinion but feel free to substantiate it.
I have deliberately used "may" because it does indeed reflect an opinion. From a C++ programmers point of view it's terribad. From a C-programmers view it admittedly doesn't look bad at all. It looks like a reasonable workaround to overcome a limitation of the language. However, using such structs breaks expectations, such as
a) that a data structure is always the same size, and that size can be determined using sizeof()
b) that an instance of that data structure looks exactly like defined in the header
c) that you can create instances normally, using alloc(sizeof(mystruct))
You need to make sure that everyone seeing that data structure definition in a header understands that (a), (b), and (c) above no longer hold, and what you are supposed to do instead. This information can only be passed by comments, not via source code, and the compiler has no way of telling whether you're doing it right.
I didn't know that this stuff is actually being supported by some compilers (or at least one?) Thanks for the link - you learn something new every day...
jschell wrote: Just as you must be careful about anything involving pointers and memory in C/C++.
That is not quite the same. See my comments above. Managing pointers and avoiding leaks is easy in comparison, and quite easily managed by a decent set of guidelines.
jschell wrote: <layer>Except that is exactly the point - it isn't known at compile time.
Maybe it isn't. But maybe it is - and that is exactly my point.
An example would be a struct for storing string-based data fields from a database, where each column of a table may have a different size. Generally you'd query the field size before allocating the proper amount of memory for your struct. But when a function references a specific field, then you know at compile time which field that is, and how much memory you need. So you could define a sufficiently large memory block an the stack to store values within that function.
Not saying that this is a good idea: where one programmer might consider 2 characters to be "sufficient" to store a year entry, others accessing the same struct might expect 4 characters. Enter the Y2K crisis!
|
|
|
|
|
Stefan_Lang wrote: From a C++ programmers point of view it's terribad
In general I would agree with that statement.
Stefan_Lang wrote: However, using such structs breaks expectations...,
I would expect that at experienced C developer would be familar with the idiom and thus would adjust their expectations accordingly.
Stefan_Lang wrote: This information can only be passed by comments
Myself I would indeed comment it. But in my experience I comment code much more than almost everyone else. I have in fact never worked with anyone that comments code as rigorously as I do.
Stefan_Lang wrote: not via source code, and the compiler has no way of telling whether you're doing
it right.
Actually the source code, as per many other idioms, is in fact a method of learning how it works. And often the only way for many idioms regardless of how apt they are or not.
And for C there are many things that the compiler can't check.
Stefan_Lang wrote: Managing pointers and avoiding leaks is easy in comparison, and quite easily
managed by a decent set of guidelines.
Myself I find using the idiom easy. There are far more complicated things in C such as building deep data hierarchies dynamically.
Stefan_Lang wrote: So you could define a sufficiently large memory block an the stack to store
values within that function.
Your description is not that clear but best I can tell it is not an apt use for this idiom. Incorrect usage does not of course invalidate the idiom itself.
|
|
|
|
|
This will just lead to program crashes, incorrect results and other strange happenings. You must not write into memory that you have not allocated in advance. If you already have the data in memory chReadData then all you need to do is set a pointer to that data which is of the structure type, like:
struct MessagData
{
DWORD dwSize;
BYTE byData[1];
}
char chReadData[100];
MessagData* pMessagData = reinterpret_cast<MessagData*>(chReadData);
One of these days I'm going to think of a really clever signature.
|
|
|
|