Fixing the code
Your code passes things of the wrong type to lfind. If the key argument is a pointer to some type T, then the base argument must be a pointer to an array of T. When you pass buffer as key, then buffer, which is an array of char, is automatically converted to a pointer to char. Thus, T is char. So base is required to be an array of char. However, your base is an array of pointers to char, so it is the wrong type.
To fix this, add this code in Unique, after buffer is defined:
char *BufferPointer = buffer;
Then, to call lfind, use:
if (!lfind(&BufferPointer, &array, &count, sizeof(char*), StringPtrCompare))
With this call, the first parameter is a pointer to a pointer to char. Thus, the type T is pointer to char. This matches &array, which is a pointer to an array of pointer to char.
Then, in StringPtrCompare, the parameters ptr1 and ptr2 will each have type pointer to T. Since T is pointer to char, the type of ptr1 and ptr2 is pointer to pointer to char. (I am ignoring the const qualifier for now.) Then you can call strcmp this way:
int StringPtrCompare(const void *ptr1, const void *ptr2)
{
return strcmp(* (char **) ptr1, * (char **) ptr2);
}
Pointers to arrays versus pointers to pointers
A pointer to an array, such as char (*)[], is not the same things as a pointer to a pointer, such as char **. If p is a pointer to an array, then, at the place where p points, there must be an array of elements: The data of the elements must be at that location.
In contrast, if p is a pointer to a pointer, then, at the place where p points, there must be a pointer: The bytes at that location must contain the value of a pointer.
An array versus the address of an array
When buffer has type char [200], it is an array of char. When you use an array in an expression, it is converted to a pointer to its first element, unless it is the operand of sizeof, _Alignof, or & or is a string literal used to initialize an array. When you pass buffer to lfind, none of those exceptions applies, so buffer is converted to the address of its first char.
When you pass &buffer, this expression is the address of the array. The address of the array has the same value as the address of its first element, but has a different type. However, when you pass either buffer or &buffer to lfind, it is converted to void *, because lfind is declared to take an argument of that type. Thus, the difference between the types of buffer and &buffer is lost, and only the value is passed. Since they have the same value, there is no difference.