I\'m using dlsym() in C and I have a question whether the return value of dlsym() should be explicitly cast or if it is implicitly cast co
dlsym() returns a void* value. This pointer value can refer either to an object or to a function.
If it points to an object, then no cast is necessary, since C defines an implicit conversion from void* to any pointer-to-object type:
int *ptr = dlsym(handle, "name");
If it points to a function (which is probably much more common), there is no implicit conversion from void* to any pointer-to-function type, so a cast is necessary.
In standard C, there's no guarantee that a void* value can meaningfully be converted to a function pointer. POSIX, which defines dlsym(), implicitly guarantees that the void* value returned by dlsym() can be meaningfully converted to a pointer-to-function type -- as long as the target is of the correct type for the corresponding function.
Assuming we're dealing with a void function with no parameters:
typedef void (*func_ptr_t)(void);
func_ptr_t fptr = (func_ptr_t)dlsym(handle, "name");
As it happens, gcc (with -pedantic) warns about this:
warning: ISO C forbids conversion of object pointer to function pointer type
This warning is not strictly correct. ISO C does not actually forbid converting an object pointer to a function pointer type. The standard lists several constraints that may not be violated by a cast operator; converting void* to a function pointer type is not one of them. The C standard doesn't define the behavior of such a conversion, but since POSIX does in this particular case that's not a problem.
A comment on Steve Summit's answer suggests that this:
*(void **) (&f) = dlsym(handle, "foo");
will silence gcc's warning. It will, but it makes assumptions that are not guaranteed by either C or POSIX. POSIX guarantees that the result of dlsym may be converted to a function pointer; it doesn't guarantee that it has the same representation or alignment. It's likely to work, but I don't recommend it.