C++ Windows DLL: Exception Handling in Different Function - c++

This is more of a design suggestion I need. Below code is from a C++ dll that am working on and this dll is called by many client executables. InputParams is a pointer to client exe.
The dll calls functions in the client to get certain values and the client doesn't have any exception build into it. So i need to implement exception handling in dll code.
for e.g., in the line input->getName, if it returns a NULL pointer or if status == ERROR, then I need to throw exception and catch it in GetNumbers function.
void Metrics::GetNumbers(InputParams* input, OutputParams* output)
{
int i, x, k;
int status = 0;
char* mesg;
try{
const char* name = input->getName(&status, &mesg); //this returns a name string
//and status will contain whether success or failure and mesg will have any error
//messages.
const char* age = input->getAge(&status, &mesg);
//Many other similar calls to client
vector <int> myVectorNumers* = input->getNumberArray(&status, &mesg);
vector <int> myVectorInfos* = input->getInfoArray(&status, &mesg);
//Many other similar calls to client;
}
catch (std::exception e&)
{
// TODO
}
catch (string msg)
{
// TODO
}
I came up with a way of doing it. And this is the snippet of code.
string errorMsg = "";
const char* name = input->getName(&status, &mesg);
if (name == NULL || status == ERROR) // ERROR == 0
{
errorMsg = mesg;
throw errorMsg;
}
const char* age = input->getAge(&status, &mesg);
if (age== NULL || status == ERROR)
{
errorMsg = mesg;
throw errorMsg;
}
//Same for other calls to client using **input** pointer
Now as you see, I have to duplicate almost the same code in every place were there should be an exception check.
What am looking for is?
string errorMsg = "";
const char* name = input->getName(&status, &mesg);
CheckException(name, status, mesg, &errorMsg); // this function should do the error check and then throw the exception. And that exception should be caught by catch block in **GetNumbers** function.
const char* age = input->getAge(&status, &mesg);
CheckException(age, status, mesg, &errorMsg);
I have no idea whether even this is possible.
So a dummy implementation of CheckException will look like......
std::exception CheckException (/*1st parameter needs to be template type*/T* var, int status, string mesg, string *errorMsg)
{
if (var == NULL || status == ERROR)
{
errorMsg = mesg;
return /*TODO*/; //Not sure how to return a throw
}
}
1st of all, is this possible? Or is there a better way of doing this?
If you can provide me some sample code, that will be great!

Exceptions are not allowed to pass over the DLL boundary into the calling executable. The caller is not guaranteed to know how to handle an exception properly, especially in regards to cleanup, even if the executable and DLL are compiled with the same compiler. Or, the caller may not even understand what an exception is at all, if the executable and DLL are compiled in different languages.
If you need to convey error information to the caller, you must do so using a return value, an output parameter, a separate function call, etc. Things that are more-or-less universally supported across compilers/languages.
DO NOT throw exceptions over the DLL boundary into the caller!
UPDATE
You are already catching std::exception& in GetNumbers() (though, it really should be const std::exception & instead), so simply have CheckException() actually throw a std::exception object, don't try to return it, eg:
template<typename T>
void CheckException (const T *var, int status, const string &mesg)
{
if (var == NULL || status == ERROR) {
// or make a custom class derived from std::exception, if you want...
throw std::runtime_error(mesg);
}
}
...
try
{
const char* name = input->getName(&status, &mesg);
CheckException(name, status, mesg);
const char* age = input->getAge(&status, &mesg);
CheckException(age, status, mesg);
// Many other similar calls to client...
vector<int> *myVectorNumers = input->getNumberArray(&status, &mesg);
CheckException(myVectorNumers, status, mesg);
vector<int> *myVectorInfos = input->getInfoArray(&status, &mesg);
CheckException(myVectorInfos, status, mesg);
// Many other similar calls to client...
}
catch (const std::exception e&)
{
// TODO
}

Related

Call of Overloaded Functions is Ambiguous

I'm getting the error call of overloaded function is ambiguous and I understand it's because the compiler can't differentiate between them, but is there a way to work around this while maintaining the same parameters? I have to use the declarations I've provided below and it's confusing me as to how I can use them both if I met with this error every time.
I've shortened my code to show the constructors that are posing the issue.
ErrorMessage.h
class ErrorMessage {
char* message_; //pointer that holds the address of the message stored in current object
public:
ErrorMessage();
explicit ErrorMessage(const char* errorMessage = nullptr); //receive address of a C-style nullterminate string holding an error message
}
ErrorMessage.cpp
namespace sict {
ErrorMessage::ErrorMessage() {
message_ = nullptr;
}
ErrorMessage::ErrorMessage(const char* errorMessage) {
if(errorMessage == nullptr) {
message_ = nullptr;
}
else {
message(errorMessage);
}
const char* ErrorMessage::message() const {
return message_;
}
}
Just remove the constructor which takes no parameters. The second constructor already does everything the first constructor does.
If it receives a nullptr, it tests it and sets the local variable, if not it continues with its logic. The first constructor is completely superfluous.

Occasional segmentation fault in a struct operator function overload

I have a C++ structure defined as follows:
typedef struct event{
int id;
string name;
//int arg0;
QByteArray data;
bool operator<(const event& e) const
{
return id < e.id;
}
bool operator==(const event& e) const
{
return id == e.id;
}
}Event;
I also have a map defined as follows:
map<string, set<Event>> mapOfEventsByString;
When I want to see if an Event is associated to a given string I use this line of code:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
{
//do stuff
}
Problem: Sometimes (and I mean that 9/10 times I can run the entire application with the exact same data set without any problems), I get a segmentation fault here:
bool operator<(const event& e) const
{
return id < e.id; <------- GIVES SEGMENTATION FAULT SOMETIMES
}
After many attempts at reproducing the error while debugging, I managed to pinpoint the segfault to that line. In that scenario e.id is filled with data and id says: "no such value".
Help?
Thank you
Without a backtrace we are only guessing, but this is a strong indication that the member id doesn't exist, so you're accessing memory you shouldn't.
If the member id doesn't exist, then your operator< call is broken. Given that it is invoked by the below highlighted part of your code:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^^^^^^^^^^^^
that suggests to me that the below highlighted expression does not assuredly refer to a valid object:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^^^^^
The only way that can happen is if the below highlighted dereference operation is invalid:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^
which occurs when the find fails, returning mapOfEventsByString.end() (which cannot be dereferenced):
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I think if you actually check for find success you'll see that, 1 out of 10 times, aString was not found in mapOfEventsByString.
Let's do this, instead:
const auto it = mapOfEventsByString.find(aString);
if (it != mapOfEventsByString.end() && it->second.count(event) == 1) {
// do stuff
}
Now you can put a breakpoint in for when it == mapOfEventsByString.end() and investigate why the find is failing. Good luck!

How to safely deal with an array pointer when throwing an exception

When trying to encapsulate C API in C++ method, i found a problem in throwing an exception:
int status;
char* log = nullptr;
int infoLogLength;
getFooStatus(&status);
getFooLogLength(&infoLogLength);
if (!status) {
log = new char[infoLogLength];
getFooLog(infoLogLength, log);
throw std::runtime_error(log);
}
I am not allowed to modify the interface methods in any way.
From what i understand, i am required to reserve memory for the method to fill, and operate on that. However, throwing the exception will return from the method, not letting me to free the resources. Is my code correct, or should i go around this in some other way?
std:runtime_error expects a std::string, so give it a std::string instead of a char*:
int status;
getFooStatus(&status);
if (!status) {
int infoLogLength;
getFooLogLength(&infoLogLength);
std::string log(infoLogLength, '\0');
getFooLog(infoLogLength, &log[0]);
throw std::runtime_error(log);
}
Alternatively, you can pass a char*, simply allocate it in a way that promoted auto-freeing, eg:
int status;
getFooStatus(&status);
if (!status) {
int infoLogLength;
getFooLogLength(&infoLogLength);
std::vector<char> log(infoLogLength);
getFooLog(infoLogLength, &log[0]);
throw std::runtime_error(&log[0]);
}
As far as I know runtime_error has two overloads, one with a const *char and another as const string&.
I believe constructing a std::string as a local variable and passing that to runtime_error should result in it being cleaned up properly.
There is a simple way to deal with exceptions, without having to refactor the code so that the array is managed by an object whose destructor cleans it up. Namely:
char* log = nullptr;
try {
int status;
int infoLogLength;
getFooStatus(&status);
getFooLogLength(&infoLogLength);
if (!status) {
log = new char[infoLogLength];
getFooLog(infoLogLength, log);
throw std::runtime_error(log);
}
} catch (...) { // special C++ syntax: "catch any exception"
delete [] log;
throw; // special C++ syntax: "re-throw" current exception
}
If all you have is a single catch (...), it looks a lot as if C++ supports finally. The difference betwen catch (...) and a finally feature is that catch (...) does not execute unconditionally: it only executes if there isn't a more specific catch. So, if you were to add additional catch clauses in the same try block, they would all have to repeat the delete [] log clean-up action.
This could be mitigated by using nesting:
try { // real exception-handling try
try { // try for unwind protection only
...
} catch (...) {
// clean-up statements
throw;
}
} catch (actual_error &err) {
...
} catch (another_exc_type &exc) {
...
}

Translate error codes to string to display

Is there a common way in C++ to translate an error code to a string to display it?
I saw somewhere a err2msg function, with a big switch, but is that really the best way?
Since C++ does not allow automatic 'translation' from enum values to enum names or similar, you need a function to do this. Since your error codes are not somehow defined in your O/S you need to translate it by yourself.
One approach is a big switch statement. Another is a table search or table lookup. What's best depends on error code set.
table search can be defined in this way:
struct {
int value;
const char* name;
} error_codes[] = {
{ ERR_OK, "ERR_OK" },
{ ERR_RT_OUT_OF_MEMORY, "ERR_RT_OUT_OF_MEMORY" },
{ 0, 0 }
};
const char* err2msg(int code)
{
for (int i = 0; error_codes[i].name; ++i)
if (error_codes[i].value == code)
return error_codes[i].name;
return "unknown";
}
In windows you can use FormatMessage(...) function either with error code return by GetLastError() function or directly to the suspected area.
Please see below links for examples.
http://msdn.microsoft.com/en-us/library/ms679351(v=VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms680582(v=VS.85).aspx
I hope this will help you.
Similar to harper's idea, but a bit more generalized:
typedef std::map<int, const char*> error_code_tbl_t;
typedef error_code_tbl_t::value_type error_code_entry_t;
const error_code_entry_t error_code_tbl_[] = {
{ ERR_OK , "ERR_OK" },
{ ERR_RT_OUT_OF_MEMORY, "ERR_RT_OUT_OF_MEMORY" },
// ...
};
const error_code_tbl_t error_code_tbl( begin(error_code_tbl_)
, end (error_code_tbl_) );
const char* err2msg(int code)
{
const error_code_tbl_t::const_iterator it = error_code_tbl.find(code);
if(it == error_code_tbl.end())
return "unknown";
return it->second;
}
(Those begin() and end() functions can be found here.)
As far as I am concerned, error codes are just a subset of enums. Since we are not blessed in C++ with pretty enums (which makes logs somehow quite hard to parse), error codes are no more easier.
The solution is pretty simple for error codes though:
class ErrorCode
{
public:
ErrorCode(): message(0) {}
explicit ErrorCode(char const* m): message(m) {}
char const* c_str() const { return message; }
std::string toString() const
{
return message ? std::string(message) : std::string();
}
private:
char const* message;
};
std::ostream& operator<<(std::ostream& out, ErrorCode const& ec)
{
return out << ec.c_str();
}
Of course you can supply the traditional ==, !=, <, etc...
It's simple!
It's fast (the code IS the string, no look-up involved)
It's type safe (you cannot accidentally mix it up with another type)
The idea is to return pointers to the text instead of error codes (though wrapped in a class for type safety).
Usage:
// someErrors.h
extern ErrorCode const ErrorOutOfMemory;
// someErrors.cpp
ErrorCode const ErrorOutOfMemory = ErrorCode("OUT OF MEMORY");
The big switch is not that bad for this. To get a string for an error code is almost always not performance critical.
You should keep in mind that these error strings are probably not what you want to show your users. The messeges for the user should be kept in resources for easier translation.
strings for error codes are for logs or diagnostics and need no translation.
You can use this trick to define your error codes and the strings in parrallel:
#if defined(ERROR_BUILD_ARRAY)
#define ERROR_START \
static const err_defn error_table[] = { \
{ WARNING, "Warning" },
#define ERRDEF(num, offset, str) { num, str },
#define ERROR_END { 0, NULL } };
#elif !defined(ERROR_ENUM_DEFINED)
#define ERROR_START \
typedef enum svn_errno_t { \
WARNING = OS_START_USERERR + 1,
#define ERRDEF(num, offset, str) /** str */ num = offset,
#define ERROR_END ERR_LAST } svn_errno_t;
#define ERROR_ENUM_DEFINED
ERROR_START
ERRDEF(ERR_BAD_BAD,
ERR_BAD_CATEGORY_START + 0,
"Bad error")
ERRDEF(ERR_BAD_FILENAME,
ERR_BAD_CATEGORY_START + 1,
"Bogus filename")
ERROR_END
(Copied from subversion sources)
I tend to avoid the switch since it's usually a big piece of code. I prefer a table lookup along the lines of:
In btree.h:
enum btreeErrors {
ZZZ_ERR_MIN = -1,
OKAY,
NO_MEM,
DUPLICATE_KEY,
NO_SUCH_KEY,
ZZZ_ERR_MAX };
In btree.c:
static const char *btreeErrText[] = {
"Okay",
"Ran out of memory",
"Tried to insert duplicate key",
"No key found",
"Coding error - invalid error code, find and destroy developer!"
};
const char *btreeGetErrText (enum btreeErrors err) {
if ((err <= ZZZ_ERR_MIN) || (err >= ZZZ_ERR_MAX))
err = ZZZ_ERR_MAX;
return btreeErrText[err];
}
Not that it usually matters since errors should be the exception rather than the rule, but table lookups are generally faster than running big switch statements (unless they get heavily optimised).
I wanted a way to have error code (int) and string description (any string) be declared in one and only one single place and none of the examples above allows that (ERR_OK has to be declared somewhere and then "ERR_OK" is mapped to it somewhere else).
So I declared a simple class storing both int and string and maintaining a static map for int->string conversion. I also added an "auto-cast to" int function:
class Error
{
public:
Error( int _value, const std::string& _str )
{
value = _value;
message = _str;
#ifdef _DEBUG
ErrorMap::iterator found = GetErrorMap().find( value );
if ( found != GetErrorMap().end() )
assert( found->second == message );
#endif
GetErrorMap()[value] = message;
}
// auto-cast Error to integer error code
operator int() { return value; }
private:
int value;
std::string message;
typedef std::map<int,std::string> ErrorMap;
static ErrorMap& GetErrorMap()
{
static ErrorMap errMap;
return errMap;
}
public:
static std::string GetErrorString( int value )
{
ErrorMap::iterator found = GetErrorMap().find( value );
if ( found == GetErrorMap().end() )
{
assert( false );
return "";
}
else
{
return found->second;
}
}
};
Then, you simply declare your error codes as below:
static Error ERROR_SUCCESS( 0, "The operation succeeded" );
static Error ERROR_SYSTEM_NOT_INITIALIZED( 1, "System is not initialised yet" );
static Error ERROR_INTERNAL( 2, "Internal error" );
static Error ERROR_NOT_IMPLEMENTED( 3, "Function not implemented yet" );
Then, any function returning int can do to return 1
return ERROR_SYSTEM_NOT_INITIALIZED;
And, client programs of your library will get "System is not initialised yet" when calling
Error::GetErrorString( 1 );
The only limitation I see is that static Error objects are created many times if .h file declaring them is included by many .cpp (that's why I do a _DEBUG test in constructor to check consistency of the map). If you don't have thousands of error code, it should be a problem (and there may be a workaround...)
Jean

C++ null string

I have a function in a C++ program returning a string.
On certain conditions, e.g. if the function encounters an error or so, I want to return a special value telling the caller that something has gone wrong.
I could basically just return an empty string "", but the function does need the empty string as normal return value.
How can I accomplish this?
Do I have do create a special data structure that for my function that holds a bool if the function was successfully run and a string containing the actual return value?
This sounds like a usecase for exceptions.
try {
std::string s = compute();
} catch(ComputeError &e) {
std::cerr << "gone wrong: " << e.what();
}
If you don't want to or can't use exceptions, you could change the function's interface
std::string result;
if(!compute(result)) {
std::cerr << "Error happened!\n";
}
Though most often, i've seen the return value is used for the actual result, and an error pointer is passed
bool b;
std::string s = compute(&b);
if(!b) {
std::cerr << "Error happened!\n";
}
This has the benefit that you can default the error argument pointer to 0 and code that can ignore the error (because it could live with an empty string return, for example, or if it knows in advance the input is valid) would not need to bother:
std::string compute(bool *ok = 0) {
// ... try to compute
// in case of errors...
if(ok) {
*ok = false;
return "";
}
// if it goes fine
if(ok) {
*ok = true;
}
return ...;
}
You can definitely return a pair, although it is klunky.
pair< string, bool > my_method(...) {
if (a) {
return make_pair(some_value, true);
} else {
return make_pair("", false); // error
}
}
pair< string, bool > result = my_method(...);
if (result.second) {
// success
} else {
// error
}
You can also pass either the bool or the string by reference,
bool my_method(string& s, ...) {
...
}
string s;
if (my_method(s, ...)) {
// success
} else {
// error
}
or:
string my_method(bool& ok, ...) {
ok = false; // default
...
}
bool ok;
s = my_method(ok, ...));
if (ok) {
// success
} else {
// error
}
You could try returning an auto_ptr to a string, but this will cost you an explicit new-ing of a string.
std::auto_ptr<std::string> Foo(int i)
{
if(i == 0) // Error!
return std::auto_ptr<std::string>(NULL);
else // Works.
return std::auto_ptr<std::string>(new string("Hello world!"));
}
If it's really something like an error, you should throw an exception. But by reading your question I guess it's not an "exceptional behaviour"?
If that's the case, you have several non-perfect solutions :
Return a structure with the string and a boolean that tells if the function failed (a simple std::pair<> could be enough).
Make your function modify a string parameter provided by reference and return a boolean telling if the function failed.
Make your function a functor/object that have a state. That state would be (at least) a boolean giving the failure or success of the last function call -- that would then be a function call.
3 is IMO bad design, while 2 and 1 are unperfect compromise.
It depends on how is your program organized.
You may return an additional boolean signifying if the function succeeded. You may return a structure containing boolean and string. You may return a special string (not necessarily empty) which should represent the failure. You may throw an exception. You may set a global flag indicating an error (though I would not recommend it).
There must be lot of other methods to express function failure, too.
The std::pair<> method is good. Another alternative is to have the caller pass the output string in as a non-const reference, and have the function return true or false depending on if an error was encountered or not.
bool Foo(int i, std::string& result)
{
bool ret = false; // no error
// do stuff...
result = "blahbalhbalh";
return ret;
}