Stack overflow地址:c++ - Dynamic Shared Library compilation with g++ - Stack Overflow
翻译:
我尝试使用g++编译下面简单的动态库程序示例代码从Program-Library-HOWTO。这只是一个示例程序,我可以学到如何使用和编写动态库。这个库的真正代码我正在使用C++编写。
#include
#include
#include
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
}
如果我使用gcc编译程序它会工作的很好:
gcc -o foo foo.c -ldl
当我修改文件名和编译期像下面这样:
g++ -o foo foo.cpp -ldl
我得到了下面的错误:
foo.cpp:16: error: invalid conversion from 'void*' to 'double (*)(double)'
我理解(我认为我理解了,如果我错了请纠正我)我不能在C++中做 void指针的隐式转换,但是C允许我这么做,这就是为什么上面的代码使用gcc可以但是使用g++不行的原因。所以我修改第16行位显式转换:
cosine = (double *)dlsym(handle, "cos");
这次替换我得到了下面的错误:
foo.cpp:16: error: cannot convert 'double*' to 'double (*)(double)' in assignment
这些问题可能与我自己对适当的C ++编码标准的比较不熟悉有关。 有人都可以告诉我一个关于开发使用C ++示例代码的Linux动态库的好教程吗?
Answers1:
C允许隐式转换从 void*到任意类型的指针(包括函数指针);C++需要显式转换。就像 leiflundgren 说的,你需要将dlsym()的返回值转换为一个你需要的函数指针。
很多人认为C的函数指针语法非常笨拙。一个通用模式是对函数指针进行 typedef:
typedef double (*cosine_func_ptr)(double);
你可以定义你的函数指针变量cosine 作为你的类型成员:
cosine_func_ptr cosine;
然后使用这个类型代替笨拙的函数指针语法:
cosine_func_ptr cosine;
Answers2:
dysym()返回一个指针符号。(作为void*是通用的)在这里你需要把它转换为函数指针。
double (*mycosine)(double); // declare function pointer
mycosine = (double (*)(double)) dlsym(handle, "cos"); // cast to function pointer and assign
double one = mycosine(0.0); // cos(0)
在这罕见的情况下,编译期错误是一个好的线索。
网友评论