Question

I'm new to C# and so forgive me if I have some of my concepts skewed. I'm working with the Canon EDSDK, and to make life easier I'd like to be able to see error messages as text rather than hex values. The EDSDK.cs file contains a long list of errors such as :

public const uint EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07;
public const uint EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08;

Ideally I'd like to put all of these into some sort of lookup table so I can input a HEX errorcode and return the actual message as a string. For example

Hashtable EDSDKErrorCodes = new Hashtable();

EDSDKErrorCodes.Add("0x00008D01", "EDS_ERR_TAKE_PICTURE_AF_NG");
EDSDKErrorCodes.Add("0x00008D08", "EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG");
etc etc...

The later in my code I could grab the error message returned from one of the EDSDK methods and display it in a human readable form :

errorcode= EDSDK.EdsInitializeSDK();

MessageBox.Show(Convert.ToString(EDSDKErrorCodes[errorcode]));

My question is .. is this a good way to handle all these error codes or is there a better and more efficient way that people would recommend? If so how I could fill my hash table as a series of constants rather than having to use the Add method?

Was it helpful?

Solution

You could use an enum for this.

public enum ErrorCodes : uint
{
    EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07,
    EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08
}

Then your usage could be something like the following:

ErrorCodes error = (ErrorCodes)EDSDK.EdsInitializeSDK();
MessageBox.Show(Enum.GetName(typeof(ErrorCodes), error));

OTHER TIPS

Another way you could do this is by creating an Enum with a description attribute. See here for the full details. This is summarizing how it would look:

public enum ErrorCodes : uint
{
    [Description("Description for EDS_ERR_TAKE_PICTURE_CARD_NG")]
    EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07,
    [Description("Description for EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG")]
    EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08
}

At the very simplest, if you didnt care about a description, you could convert the enum name to string using Enum.GetName

I would think making an enum would be superior:

public enum CanonErrorCode
{
    SomeErrorDescription = 14,
    SomeOtherErrorDescription = 15
    // .. etc
}

You simply do the conversion from hex to integer. Then you can simply call it like so:

// Samples
var myErrorCode = (CanonErrorCode)someIntegerValue;
var myErrorCode = CanonErrorCode.SomeOtherErrorDescription;

If you want human formatted error descriptions, then I would suggest some kind of mapping like:

static Dictionary<int, string> errorlookups = new Dictionary<int, string>();

errorLookups.Add(10, "This is the human readable error message.");
errorLookups.Add(17, "Create this guy once in a static constructor.");

You could use a Generic Dictionary instead of a hashtable

Dictionary<uint, String> myDict = new Dictionary<uint, String>();

You can then retrieve the value you want by doing

MessageBox.Show(myDict[errorCode]);

For adding, I think you might be able to do something with reflection to reflect over the EDSDK class and find all the constant uint members. Then iterate through that list adding the value and the constant name.

Ok, another take since we are rolling :-)
This solution also produces a human-readable error string if the current error code is not defined.

Create an Enum like so:

public enum ErrorCode : uint
{
    EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07,
    EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08
}

Then, create an Extension Method for the enum type like this:

public static class ErrorHandler
{
    public static string ToErrorString(this ErrorCode errorCode)
    {
        return Enum.IsDefined(typeof(ErrorCode), errorCode) ? 
            errorCode.ToString() : "Undefined error code";
    }
}

And finally, use it like that:

var errorCode = (ErrorCode)EDSDK.EdsInitializeSDK();
MessageBox.Show(errorCode.ToErrorString());

First of all, you should use a generic dictionary instead of a hashtable. Second, I don't know anything about the Canon EDSDK, but it seems odd that it returns an error code as a hex string rather than simply a uint as the constants are defined. Is that really how they are being returned? If so, that's weird, but you should be able to convert them to an integer, otherwise, you can skip that step.

If you want to create the array using reflection, you could do something like this:

Dictionary<int,String> EDSDKErrorCodes = new Dictionary<int,String>;
System.Reflection.FieldInfo[] fields = typeof(EDSDK).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
foreach (System.Reflection.FieldInfo field in fields) {
  EDSDKErrorCodes[(uint)field.GetValue(null)] = field.Name;
}

And you can then access it using:

MessageBox.Show(EDSDKErrorCodes[errorCode]);

If errorCode is a string, convert it first using:

uint errorNumber = uint.Parse(errorCode.Substring(2), System.Globalization.NumberStyle.HexNumber);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top