用g ++dynamic共享库编译

我试图用g ++编译以下简单的DL库示例代码,从Program-Library-HOWTO 。 这只是一个例子,所以我可以学习如何使用和编写共享库。 我正在开发的库的真实代码将用C ++编写。

#include <stdlib.h> #include <stdio.h> #include <dlfcn.h> 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:错误:从'void *'无效转换为'double(*)(double)'

我明白(我我理解,纠正我,如果这是错误的),我不能做一个隐式强制从C ++中的指针,但C让我,这就是为什么上面的代码将使用GCC编译,但不使用克++。 所以我试图通过改变上面的第16行显式强制:

 cosine = (double *)dlsym(handle, "cos"); 

有了这个,我得到以下错误:

foo.cpp:16:错误:无法在赋值中将“double *”转换为“double(*)(double)”

这些问题可能更多地与我自己对适当的C ++编码标准的一般无知相比。 任何人都可以点我一个很好的教程开发使用C + +示例代码的Linuxdynamic库?

Solutions Collecting From Web of "用g ++dynamic共享库编译"

C允许从void *到任何指针类型(包括函数指针)的隐式转换; C ++需要显式的投射。 正如leiflundgren所说,您需要将dlsym()的返回值转换为您需要的函数指针类型。

很多人觉得C的函数指针语法很尴尬。 一种常见的模式是键入下面的函数指针:

 typedef double (*cosine_func_ptr)(double); 

你可以定义你的函数指针变量cosine作为你的类型的成员:

 cosine_func_ptr cosine; 

而使用类型而不是尴尬的函数指针语法进行投射:

 cosine = (cosine_func_ptr)dlsym(handle, "cos"); 

dlsym返回一个指向符号的指针。 (因为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) 

所以在这种罕见的情况下,编译器错误是一个很好的线索。 ;)

用你的代码写的方式,这实际上是一个C的问题,但你可以得到这个将在C ++中工作。 我没有关于动态共享库(您链接到的网页看起来不错)的教程,但下面是如何使用C ++修复代码:

  • 声明my_cos是一个将(最终)调用动态加载的余弦函数的函数:

     double my_cos(double); 
  • 将函数指针分配给my_cos

     my_cos = (double (*)(double)) dlsym(handle, "cos"); 

这有点复杂,但它分配给my_cos返回一个double,是取消引用另一个函数指针的结果,并将double作为参数。 正如其他人所发布的那样,C ++对于代码的明确性要求比C要高一些。

  • 用std :: cerr或std :: cout替换那个过时的fputs消息:

     std::cerr << "error loading library cos: " << error << std::endl; 

 std::cout << "result is " << (*my_cos)(2.0)) << std::endl; 

希望这有助于。 如果那怪异的东西吓到你,我会推荐van Linden的Deep C Secrets,肯定是C上的coreighan和Ritchie Book。

编辑:关于如何专门寻找C ++而不是C的开发指南,以避免这种类型的问题的评论中的好点。 我不知道C ++中的类似指南,但是大约99%的C代码可以嵌入到C ++代码中,并且工作得很好。 这个函数指针的情况是一个例外。