Generic enum to text lookup in C Can my code from this question be improved? I am thiking of validating inputs, portability issues, etc

Please note that we must declare our strings at compile time. We code embedded systems and are not allowed to malloc().



[Update]

I forgot to state that our enums are non-contiguous and have a wide range, which can make a difference.



Here's some test data:  

// +=+=+=+=+=+=+=+=+=+=+=+=+=+=
typedef enum
{
    north,
    south,
    east,
    west
} E_directions;

struct direction_datum
{
    E_directions direction;
    char         direction_name[6];
};

struct direction_datum direction_data[] =
{
    {north, "north"},
    {south, "south"},
    {east,  "east"},
    {west,  "west"},
};

// +=+=+=+=+=+=+=+=+=+=+=+=+=+=
typedef enum
{
    hearts,
    spades,
    diamonds,
    clubs,
} E_suits;

struct suit_datum
{
    E_suits suit;
    char    suit_name[9];
};

struct suit_datum suit_data[] =
{
    {hearts,   "hearts"},
    {spades,   "spades"},
    {diamonds, "diamonds",},
    {clubs,    "clubs"},
};


and, here's the code, which should  get text from an enum, as defined by a struct of enum/string, where different structs can have different length arrays.:

#define ARRAY_LENGTH(A) sizeof(A) / sizeof(*A) 

char *Get_text_from_enum(int enum_value, 
                         void *array, 
                         unsigned int array_length, 
                         unsigned int size_of_array_entry)
{
    unsigned int i;
    unsigned int offset;

    for (i = 0; i &lt; array_length; i++)
    {
        offset = i * size_of_array_entry;

        if ((int) * ((int *) (array+ offset)) == enum_value)
            return (char *)  (array + offset + sizeof(int));
    }

    return NULL;
}


printf("Expect south,    got %s\n", 
          Get_text_from_enum(south,    
                             direction_data, 
                             ARRAY_LENGTH(direction_data),  
                             sizeof(direction_data[0])));

printf("Expect diamonds, got %s\n", 
          Get_text_from_enum(diamonds, 
                             suit_data,      
                             ARRAY_LENGTH(suit_data),       
                             sizeof(suit_data[0])));
Illegal void pointer arithmetic
This code is illegal in C:
void *array;
... (array + offset)

You are not allowed to do pointer arithmetic on a void * pointer.  You should use char * instead of void *.
Simplifications
I would suggest defining a generic structure like this:
typedef struct EnumName {
    int         value;
    const char *name;
} EnumName;

to avoid all of the struct length shenanigans.  You can also make it a rule that each EnumName array must be terminated with a NULL name.  This rule allows you to avoid passing in an array length argument.  Then your code would look like this:
const EnumName direction_data[] =
{
    {north, &quot;north&quot;},
    {south, &quot;south&quot;},
    {east,  &quot;east&quot; },
    {west,  &quot;west&quot; },
    {0,      NULL  },
};

const char *Get_text_from_enum(int enum_value, const EnumName *names)
{
    while (names-&gt;value != enum_value &amp;&amp; names-&gt;name != NULL)
        names++;
    return names-&gt;name;
}

int main(void)
{
    printf(&quot;Expect south,    got %s\n&quot;,
            Get_text_from_enum(south, direction_data));
}