|
Windows 7, Visual Studio 2008, C++, MFC
I cannot cut and paste to this forum so please exclude minor typos.
Here is the first class declaration:
Class C_AR2_Messages
Public:
Class C_AR2_Messages();
~ Class C_AR2_Messages();
Private:
…
// friend void_C_Configuration_Manager( const C_AR2_Messages & );
// I found the template for this somewhere and presume that C_Configuration_Manager needs to be given the address of AR2_Messages so it can find variables declared private.
};
A fragment from the definition of C_AR2_Messages:
bool C_AR2_Messages::Configure_The_Application()
{
C_Configuration_Manager *Message_Configurator;
Message_Configurator = new C_Configuration_Manager;
… }
This all compiles as shown with no errors.
HOWEVER: when the friend line is uncommented out the compiler complains with the error:
Quote: C2061: ‘Message_Configurator’ : undeclared identifier.
It references that line so marked above. (Not the "friend" line in the declaration.) Since that is a pointer declaration I do not understand how the addition of the friend line causes it to become undeclared.
A google search returned what seems to be a good match for this problem, but I am on a military base and the firewall says that site is prohibited.
Will someone please enlighten me?
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
modified 30-Jun-14 12:24pm.
|
|
|
|
|
It needs a forward declaration of void_C_Configuration_Manager class.
Do as follows.
class void_C_Configuration_Manager;
Do it in the header.
|
|
|
|
|
Windows 7, Visual Studio, C++, MFC dialog
A MFC dialog calls _beginthreadex and starts procedure Start_Server_As_Thread as a new thread.
That procedure instantiates class C_Server_Thread then calls a method that loops until an event indicates time to exit. That class creates a new instance of C_Log_Writer to write information to a log file.
The appropriate event is set, and the main loop exits.
Immediately on regaining control, procedure Start_Server_As_Thread deletes the class with:
delete mp_C_Server_Thread;
The destructor of that class is not called. The destructor contains the code
delete mp_C_Log_Writer;
which does not get run resulting in a memory leak.
I was under the impression that explicitly deleting an instance of a class forced the destructor to be called. What should I do to get that destructor called?
In the code that detects said event I can add a line to delete the logger class. Still, the question will remain, why is the destructor not called?
Edit:
Just for completeness, a silly mistake that I looked right at several times before finally stepping through the code one step at a time.
if( mp_C_Log_Writer == NULL )
{
delete mp_C_Log_Writer;
mp_C_Log_Writer = NULL;
The == should have been !=. Lesson learned again, always step through every line of code with the debugger at least once. Sorry to trouble anyone over this.
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
modified 29-Jun-14 16:55pm.
|
|
|
|
|
Is mp_C_Server_Thread of type C_Server_Thread* , or a base class? If it is abase class pointer, and the base class does not have a virtual destructor, the derived class destructor will not be called.
You are right, calling delete on a pointer will call the pointer type's destructor, if any, but without more code to look at it's very hard to say what the problem might be. For instance, are you absolutely sure that Start_Server_As_Thread does regain control, and that the delete call is executed?
|
|
|
|
|
Here is the procedure that is started as the new thread. It instantiates a class then runs the main method of that class.
unsigned int __stdcall Start_Server_As_Thread( void * p_void_pointer )
{
C_Server_Thread *mp_C_Server_Thread = NULL;
WCHAR m_log_file_text[ MAX_LOG_STRING_LENGTH ];
mp_C_Server_Thread = new C_Server_Thread( p_void_pointer );
mp_C_Server_Thread->Main_Thread_Loop();
delete mp_C_Server_Thread;
mp_C_Server_Thread = NULL;
_endthreadex( 0 );
return 0;
}
That class is declared as follows
class C_Server_Thread
{...}
The class it creates is declared:
class C_TCP_API_Server
{...}
Class C_Server_Thread manages all the overhead and communications between the main app and the thread. It instantiates C_TCP_API_Server, which does all the low level work of establishing a TCP/IP link with the client and sending the data.
Does that provide any useful information?
Edit: I continue to work this and am not certain where the problem is, but am becoming more certain that PEBKAC (Problem Exists Between Keyboard And Chair). It is looking more and more like a logic error in how I end this thing. Class C_Server_Thread could be in any of several states when it gets the event to exit. (Not connected to client, connected to client, sending data, etc) I need to work over the logic of what should be done for each state to ensure an orderly shutdown, not to mention complete shutdown.
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
modified 27-Jun-14 21:26pm.
|
|
|
|
|
Windows 7, Visual Studio 2008, C++
I am creating a console type application that uses events and an MFC dialog app just to test it. The app uses WaitForMultipleObjects() with the attendant array of events. The dialog will show the count of events set and detected. The code to update the dialog and show those counts begins like this:
void CTest_ServerDlg::OnBnClickedBtnUpdateThreadEvents()
{
const unsigned int NUMBER_SIZE = 8;
WCHAR text_value[ NUMBER_SIZE ];
int t;
t = m_common_data.thread_event_detects[ 0 ];
swprintf_s( text_value, NUMBER_SIZE, L"%03D", t );
m_thread_event_00.SetWindowTextW( text_value );
}
m_thread_event_00 is the name of the control variable assigned to the static text control in the dialog. Presume there are 16 events. I am new to Dialogs and their controls so that means there will be 16 static text controls, each with its own named variable.
The Question:
Can this setup be arranged so that the values can be updated via an iteration rather than copying the last three lines 15 more times and changing the thread_event_detects[ 0 ] and m_thread_event_00 to increment up to 15?
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
Yes, you can use GetDlgItem()[^] on the static window's resource ID (returns CWnd* but you can cast that to whatever you need). As long as your resource IDs are contiguous, you can start at the first resource ID and increment the value as you iterate through them. Check the resource file for the actual numbers associated with the ID.
|
|
|
|
|
Windows 7 and XP, Visual Studio 2008, 2010, C++, MFC, Windows 32 application.
I am getting frustrated with the various types of strings. With all the articles I find and often opposing points of view, I wish to limit my options and seek your opinion.
I write telemetry code that must run quite fast and move much data. The strings I deal with are mostly to log data so I can see how the code works. The end product will be a windows application that really needs no user interface.
However, during development, and because a vendor uses MFC and C++, I wish to develop in that environment. I have no desire to explicitly exclude other operating systems, but I really do not expect to use anything other than Windows XP and Windows 7 any times soon.
Which option is best: WCHAR, wchar_t, CString, char[], or something else?
edit: I forgot that WCHAR is just a typedef of wchar_t. Which does not seem very bright. Would it be wise to drop all use of WHAR and replace with wchar_t?
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
modified 13-Jun-14 11:08am.
|
|
|
|
|
IT depends on what you are trying to do, and what may change in the future. If you want a simple self-managing string type and you have MFC, then use CString . If you want speed and more control of the string data then use character arrays. If you choose the latter course then your decision will be based on the type of data that you are processing: if it is ASCII data then use char arrays, if Unicode use WCHAR arrays.
|
|
|
|
|
The fundamental purpose is to capture telemetry data, all numbers, reformat them, and send them to another computer.
HOWEVER: as often needed, I need insight into the application. Keeping this short: An MFC is used and sometimes an AFXMsgBox window is needed to inform the user of errors detected. There is also a log file. It needs to be read to see how the program operated.
Does that help narrow the field?
Edit:
I read that I really should switch to Unicode, so I did and started using WCHAR. Now I discovered that it is just a retype of wchar_t, and further that it is Microsoft unique. I do not expect to write code that can be dropped into a Unix machine and compiled, but would like to be reasonably compatible. So what the heck should be used?
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
modified 13-Jun-14 16:27pm.
|
|
|
|
|
bkelly13 wrote: Does that help narrow the field? Not really, since all of those issues may be handled in ASCII or Unicode without any problems. You omitted to explain the format of the input data: numbers as in characters (ASCII or Unicode), or numbers as in binary values? And, if the latter what do you convert them into (if anything).
If you are using Unicode for all your text then stick with WCHAR, since it's a macro and can be defined to equate to any native unicode type on other platforms.
|
|
|
|
|
The data is received as binary values and is signed, unsigned, with sizes from 1 bit per parameter to 32 bits. Some value are floating point number. All binary format, no text in any form. My application picks them out of the stream, shifts them into the correct position, applies scale and offset, assigns identifying tag numbers, and TCP the data out to a display device.
The text is used to create a configuration file for each of the different telemetry types. That is done with VBA for Excel that I write. Log files that show performance are in a text format that are read with Microsoft Wordpad. The startup configuration work and the performance monitoring use text. All the primary operations are shuffling binary data around and do not use any text.
Your comment that WCHAR can be redefined to something else for another device was a revelation. Simple and obvious and completely missed. It makes a rather big difference. Thank you for the idea.
I was thinking of std::string. Do you think that would be a valid choice? Because of your comment it is not as likely, but I would like to hear you thoughts on that anyway.
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
bkelly13 wrote: I was thinking of std::string That would also be a valid choice, although be aware that std::string is ASCII only, for Unicode you need to use std::wstring . I tend to use a typedef to define my own type which will be ASCII or Unicode, dependiing on the project settings. Something like:
#if defined(UNICODE)
typedef std::wstring STRING;
#else
typedef std::string STRING;
#endif
Then I just use STRING everywhere in the rest of the code, and the compiler sorts it out for me.
From your comments above and the description of what your code is required to do, it seems that the choice is far less important than your first message implied.
|
|
|
|
|
Re: well, yes and no. It is less important on this particular project. It is more important in that as I become used to one type or the other I will tend to use it on subsequent projects.
Not very many people/places are heavy into telemetry and some of those are unix/linix shops. WCHAR is fine, but I am thinking that std::wstring might be the better option. The TCP/IP will make it difficult to port, but I can do little about that. (Well, not true, but out of scope.)
Thank you for taking the time to reply.
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
bkelly13 wrote: The TCP/IP will make it difficult to port If you stick to the basic TCP/IP functions (connect , listen , send , recv ) it will port with no problems.
|
|
|
|
|
I am writing this to use non-blocking and overlapped with events to signify I/O completion. The WSA* calls are used. Does that reduce portability?
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
Yes, WSA functions are all Windows sockets, so not directly portable. Although you could always write some code of your own to cater for that if necessary.
|
|
|
|
|
Sometimes you need both.
For UTF-8 unicode I use std::string
For UTF-16 unicode I use std::wstring
|
|
|
|
|
Widows 7, Visual Studio 2008, C++, socket operations
My app posts a listen using a socket set to non-blocking. The debugger steps over that line, with a noticeable pause, and continues. The netstat command showed that a listen was in progress.
I can think of a few possibilities to end the listen().
1. Client connects
2. Call some method to terminate the listen.
3. Delete the object that initiated the listen
If the client does not connect, how should the app close the listen() operation?
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
Typically in Windows just closing the socket causes the listen to terminate.
|
|
|
|
|
I will do it that way. Thank you.
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
Windows 7, Visual Studio 2008, MFC, C++
A thread is started when a dialog button is clicked. The thread performs some tasks than sets event 100, an arbitrary number for conversation. The dialog is to detect that event and display some text without user intervention. What can be done in the dialog to accomplish this?
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
It would be a better idea to use the proper Windows mechanisms. When the thread has completed its task it should send a message to the dialog.
|
|
|
|
|
Valid point. But this thread is will operate in an environment with no window and will set several events multiple times before exiting. No messages, only events. MFC and the dialog are being used as a test vehicle to get close to the thread during development.
Maybe I should switch to a console environment now. Or continue on a use a button to poll for events then update the status as appropriate.
Thank you for your time
If you work with telemetry, please check this bulletin board: www.irigbb.com
|
|
|
|
|
bkelly13 wrote: an environment with no window and will set several events Without knowing how and where it sets these events it's difficult to suggest anything else. However, you may like to look into the various IPC mechanisms[^].
|
|
|
|
|