我试图从Program-Library-HOWTO使用g ++编译以下简单DL库示例代码。这只是一个例子,所以我可以学习如何使用和写入共享库。对我开发库的实际代码将用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:错误:从 '无效*' 无效转换 '双(*)(双)'
我明白了(我想我明白,纠正我,如果这是错误的),我不能这样做从C ++中的空指针隐式转换,但是C让我,这就是为什么上面的代码将编译使用gcc但不是使用克++。所以,我想有明确的转换,通过改变以上线路16:
cosine = (double *)dlsym(handle, "cos");
有了这个地方,我得到以下错误:
Foo.cpp中:16:错误:不能将 '双*' 到 '双(*)(双)' 的分配
这些问题可能有更多的事情要做适当的C ++编码比什么都重要的标准是我自己一般的无知。任何人都可以点我使用C ++示例代码开发的动态库用于Linux的好教程?
C允许从void *
到任何指针类型(包括函数指针)隐式转换; C ++需要显式类型转换。作为leiflundgren说,你需要dlsym()
的返回值转换为你需要的函数指针类型。
很多人觉得C'S函数指针语法尴尬。一个常见的模式是的typedef函数指针:
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 ++:
double my_cos(double);
my_cos = (double (*)(double)) dlsym(handle, "cos");
这是一个有点复杂,但它分配给my_cos东西,返回了一倍,是另一种解引用函数指针的结果,并采取双重作为参数。至于其他人已经发布,C ++是一个更苛刻一点关于你的代码要比C的明晰
std::cerr << "error loading library cos: " << error << std::endl;
和
std::cout << "result is " << (*my_cos)(2.0)) << std::endl;
希望这种帮助。如果怪异casty东西让你害怕,我建议深度C秘密由van林登,绝对的Kernighan和Ritchie书C.
编辑:在关于如何你专门找在C ++而不是C开发指南,以避免此类问题的意见好一点。我不知道C ++可比指导,但C代码约99%,可嵌入C ++代码和工作就好了。这个函数指针的情况是一个例外。
在C ++中,你必须执行reinterpret_cast
(不是C施法):
typedef double (* double_from_double_function_t(double));
…
double_from_double_function_t cosine = reinterpret_cast<double_from_double_function_t>(dlsym(handle, "cos"));