I need to dynamically link to a library function at runtime in Mac OS X. Following Apple's example, I declare a function pointer and assign it with the result of dlsym(). The following example compiles successfully as a plain C (.c) file. But I need this in a C++ file, and if I compile this example as a C++ file (.cpp), the clang compiler tells me
Cannot initialize a variable of type 'void ()(char *)' with an rvalue of type 'void '
Why does it work in plain 'C', and how can I fix this?
#include <dlfcn.h>
void Test() {
// Load the library which defines myFunc
void* lib_handle = dlopen("myLib.dylib", RTLD_LOCAL|RTLD_LAZY);
// The following line is an error if compiled as C++
void (*myFunc)(char*) = dlsym(lib_handle, "myFunc");
myFunc("Hello");
dlclose(lib_handle) ;
}
Pointers give greatly possibilities to ‘C’ functions which we are limited to return one value. With pointer parameters, our functions now can process actual data rather than a copy of data. In order to modify the actual values of variables, the calling statement passes addresses to pointer parameters in a function.
6) Like normal data pointers, a function pointer can be passed as an argument and can also be returned from a function. For example, consider the following C program where wrapper() receives a void fun() as parameter and calls the passed function. // A simple C program to show function pointers as parameter.
We called the appropriate array element (Function pointer) with arguments, and we store the result generated by the appropriate function. The instruction int (*ope [4]) (int, int); defines the array of function pointers.
Void pointers are used during function declarations. We use a void * return type permits to return any type. If we assume that our parameters do not change when passing to a function, we declare it as const.
dlsym
returns void*
. In POSIX (but not standard C, as James points out) there's an implicit conversion from void*
to a pointer-to-function type, so the assignment to myFunc
just works. In C++ there is no implicit conversion (because it's not type safe), so you need to tell the compiler that you really mean it by adding a cast:
void (*myFunc)(char*) = (void(*)(char*))dlsym(lib_handle, "myFunc");
(or you can get fancy with a reinterpret_cast
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With