|
First of all an apartment is an abstract concept, means, there is no physical thing behind. When a thread starts it decides in which apartment it wants to "live". It does so by calling CoInitialize or CoInitializeEx .
An apartment is a kind of a convention how to handle things. A thread that initializes a single-threaded apartment states, that it does not allow any other threads to enter the same apartment. COM knows then, that all objects living in this apartment can be accessed only from this same thread and makes sure that these objects are used only from within this thread.
A thread that initializes a multi-threaded apartment allows other threads. COM knows then, that multiple threads might access the objects in this apartment and relies on these objects to handle thread synchronization by themselfs.
So how do other threads enter the same apartment? Simply also via CoInitializeEx . By requesting a multi-threaded apartment they will automatically resist in the same apartment as the other MTA threads since there can only be one MTA.
So in the end each thread that initializes a STA creates its own apartment, while threads initializing MTA enter the one and only MTA. And the same is of course valid for all COM objects created from this thread.
|
|
|
|
|
|
my code:
class ATL_NO_VTABLE CSysLog :
.....
{
public:
[export]
enum EnumLogLevel
{
LogNone = 0,
LogError = 1,
LogWarning = 2,
LogInfo = 3,
LogDebug = 4,
LogDebug1 = 5,
LogDebug2 = 6,
LogDebug3 = 7,
LogDebug4,
};
......
it takes errors likes:
c1xx : error C3174: ....
LINK : fatal error LNK1250: ...
how to correct it?
|
|
|
|
|
Declare it in IDL e.g.
typedef [v1_enum] enum LogLevel
{
None = 1,
Error = 2,
Warning = 3
}LogLevel;
Use it in an interface parameter if you need to export a method:
interface IMyErrors : IDispatch {
HRESULT GetCurrentError(LogLevel udtLevel,...
...
Compile and and export as a type library or .dll or import the IDL into a .h file
|
|
|
|
|
#include<stdio.h>
#include<conio.h>
int *val1,*val2;
int *oper;
void calc(val1,val2,oper)
{
switch(*oper)
{
case '+':printf("%d",*val1+*val2);
break;
case '-':printf("%d",*val1-*val2);
break;
case '*':printf("%d",*val1 * *val2);
break;
case '/':printf("%d",*val1 / *val2);
break;
default:printf("invalied input");
}
}
void main()
{
int num1,num2;
int oper1;
printf("Enter 2 number and an operator\n");
scanf_s("%d%d%d",&num1,&num2,&oper1);
//fflush(stdin);
calc(&num1,&num2,&oper1);
_getch();
}
it is showing all of the following ERRORS
Error 2 error C2017: illegal escape sequence c:\users\lina\desktop\project7\project7\source.cpp 33 1 Project7
Error 1 error C2448:
Error 3 error C3861:
6 IntelliSense: variable "oper" is not a type name c:\Users\Lina\Desktop\Project7\Project7\Source.cpp 7 21 Project7
4 IntelliSense: variable "val1" is not a type name c:\Users\Lina\Desktop\Project7\Project7\Source.cpp 7 11 Project7
5 IntelliSense: variable "val2" is not a type name c:\Users\Lina\Desktop\Project7\Project7\Source.cpp 7 16 Project7
|
|
|
|
|
Please format the code block properly, and identify line 33.
Use the best guess
|
|
|
|
|
Replace
int *val1,*val2;
int *oper;
void calc(val1,val2,oper)
with
void calc(int* val1,int* val2,int* oper)
|
|
|
|
|
Windows 7, Visual Studio 2008, MFC, C++, Dialog
My application makes use of an std::map, inserting records with the following:
m_tmats_definition_map[ the_key ] = m_one_definition_record;
the_key is a CString and m_one_definition_record is a structure of several CStrings and a few various fields such as integers.
That seems to be working. Now in the event something does not work out right I want some error checking. I am not finding much of anything concerning run time checking on this insert operation. Probably not looking in the right places or using the right search phrase. Where can I look to find a good discussion on this topic?
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
ouch - hard question - I just had a look and its a right PITA - 'Dinkumware' and SGI used to have good manuals (and even finding what exceptions are thrown within is hard enough)
SGI's manual page for MAP is ... http://www.sgi.com/tech/stl/Map.html[^]
that may give you a start point - what sort of error's do you expect ? dont forget that map doesnt throw an error for a duplicate key value (the commonest issue I guess) - it simply replaces the existing value... for that reason, you should use find() first on the map to see if the value already exists
'g'
|
|
|
|
|
I don't know what sort of errors to expect. Isn't that one of the joys of software? <grin>
Good link.
Good point with the Find(). I do want to know if there are duplicates and will incorporate that.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
You need to check return values of function calls that provide information. See here[^] for the insert function.
Use the best guess
|
|
|
|
|
In this case, there's nothing you need to do. If something goes wrong, it'll throw a C++ exception. Most likely causes will be that a new element can't be constructed, or that there is insufficient memory.
But maybe this is not what you meant. You say you want error checking; why do you want error checking? What is that you want to accomplish? Perhaps the solution is different.
|
|
|
|
|
Windows 7, Visual Studio MFC, C++, dialog based project
A dialog is to have a status display area. The code will add lines of text. My preference is for each new line of text to be added to the bottom and have the display scroll up. The user will not be able to edit the text, but it would be nice to be able to capture it with ctl-c to paste somewhere else.
I tried an edit control but each update wipes out the previous text.
List box seems to be the simplest control, yet still has many user accessible features.
I would like to read your reccomendations.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
|
Windows 7, Visual Studio 2008, MFC, CPP, std::map
I am trying to get an std::map working. I have tried several permutations and patterned it after some tutorials found with a search. Still I am unable to get it right and to decipher the error message.
Please assist with this problem.
The setup
typedef struct
{
unsigned int identifier_location;
unsigned int count_found;
CString key;
CString token[ MAX_TOKEN_COUNT ];
} td_tmats_attributes_definitions;
td_tmats_attributes_definitions m_one_definition_record;
std::map < CString, td_tmats_attributes_definitions > m_tmats_definition_map;
// ^ the key ^the data to store
// below is an alternate declaration.
std::map < string, td_tmats_attributes_definitions > m_tmats_definition_map_string;
And now the code
CString the_key;
…
The code:
m_tmats_definition_map.insert( the_key, m_one_definition_record );
string str_key = the_key;
Neither of the two options will compile.
I was prepared to post the error message, but I have a strong suspicion that reader will know my error with little effort and the long text from VS output box will only clutter things up. Let me know if you want to see the error text.
Please tell me what I need to change.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
modified 9-Jun-13 12:44pm.
|
|
|
|
|
m_tmats_definition_map.insert( std::make_pair(the_key, m_one_definition_record) );
OR
m_tmats_definition_map[the_key] = m_one_definition_record;
std::make_pair should be in the <utility> include.
|
|
|
|
|
As you already know, that compiles. I see the second option as being a bit more clear and used it.
Thank you for your time.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
Windows 7, 64 bit, Visual Studio 2008, MFC, C++
After a long series of searches looking for a nice method of reading from a text file into CString I arrived at the following:
<br />
CStdioFile definition_file;<br />
try<br />
{<br />
definition_file.Open( m_definition_file_name, CFile::modeRead );<br />
}<br />
catch( CFileException e )<br />
{<br />
e.m_cause;<br />
}<br />
This is from the VS help utility:
<br />
catch( CFileException* e )<br />
{<br />
if( e->m_cause == CFileException::fileNotFound )<br />
printf( "ERROR: File not found\n")<br />
e->Delete();<br />
}<br />
This leads to the concept
<br />
if( e->m_cause == CFileException::fileNotFound )<br />
printf( "ERROR: File not found\n");<br />
elseif( e->m_cause == CFileException::generic )<br />
printf( "ERROR: An unspecified error occurred.\n");<br />
elseif etc etc<br />
Is there a better way of capturing the text of the error rather than an if/else/else/else sequence?
Note: I am open to any type of suggestion. The goal is to read a CSV text file and parse it into a std::map.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
|
Cool.
Thank you.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
Oops, I have a follow up on this.
Declarations:
CFileException get_error_message;
const unsigned int ERROR_MAX = 64;
char char_error_text[ ERROR_MAX ];
LPTSTR ptr_error_text = &char_error_text[0];
CString final_error_message = "";
Code:
m_definition_file_name += "x";
try
{
m_definition_file.Open( m_definition_file_name, CFile::modeRead );
get_error_message.GetErrorMessage( ptr_error_text, ERROR_MAX, NULL );
final_error_message = char_error_text;
error_number = GetLastError();
}
catch( CFileException e )
{ code }
catch( ... )
{ code }
{
The line m_definition_file_name += "x" forces the file name to be incorrect.
Char array char_error_text winds up with "No error occurred." while error_number gets 0 (zero)
When the line error_number = GetLastErrror is moved directly beneath the open command, it get the value 2 (two). But that consumes the last error and get_error_message does not get anything.
Nothing is thrown and neither catch is activated.
What do I need to change to use this CFileException?
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
I don't understand what you are doing here; it should be:
try
{
}
catch (CFileException ce)
{
TCHAR message[132];
if (ce.GetErrorMessage(message, 132, NULL)
{
}
}
Use the best guess
|
|
|
|
|
Hello,
I don't see what you have different. Second, when the file does not exist, this Open method does not throw an exception, so none of the try/catch matters. I had a catch(...) at the bottom and it was not entered.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|
|
If the open function does not throw an error then you need to check the return value and call GetLastError() to find out why, as described here[^]. Alternatively you can throw a new exception like:
try
{
if (!m_definition_file.Open(m_definition_file_name, CFile::modeRead))
{
DWORD error_number = GetLastError();
throw new CFileException::OsErrorToException(error_number);
}
}
catch( CFileException e )
{
}
Note that when calling GetLastError() you must call it immediately after the failing API function call, otherwise its return may not be valid.
Use the best guess
|
|
|
|
|
I have also tried this.
Declarations:
const unsigned int ERROR_MAX = 64;
char char_error_text[ ERROR_MAX ];
LPTSTR ptr_error_text = &char_error_text[0];
CString final_error_message = "";
With this code
m_definition_file.Open( m_definition_file_name, CFile::modeRead );
error_number = GetLastError();
format_message_return = FormatMessage( 0, // dwFlags
NULL, // lpSousrce
error_number, // dwMessageID
NULL, // dwLanguageId
ptr_error_text, // lpBuffer
ERROR_MAX, // nSize
NULL ); // Arguments
final_error_message = char_error_text;
The error number is 2 (two). char_error_text ends up with nothing. I am uncertain of the arguments for FormatMessage. The file name is forced to be incorrect and an error is expected.
Thanks for your time
If you work with telemetry, please check this bulletin board: http://www.bkelly.ws/irig_106/
|
|
|
|