动态共享库编译使用g ++

问题描述 投票:12回答:4

我试图从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++ linux g++ shared-libraries
4个回答
26
投票

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");

9
投票

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)

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


0
投票

如果有了书面的方式你的代码,这实在是多一个C的问题,但你能得到这个会用C ++工作。我没有对动态共享库(您链接到看似正常的网页)为您的教程,但在这里是如何解决你的代码在C ++:

  • 声明my_cos是将(最终)调用动态加载的余弦函数的函数: double my_cos(double);
  • 分配函数指针my_cos my_cos = (double (*)(double)) dlsym(handle, "cos");

这是一个有点复杂,但它分配给my_cos东西,返回了一倍,是另一种解引用函数指针的结果,并采取双重作为参数。至于其他人已经发布,C ++是一个更苛刻一点关于你的代码要比C的明晰

  • 更换一个std :: CERR或std ::法院,与其约会的fputs消息: 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 ++代码和工作就好了。这个函数指针的情况是一个例外。


0
投票

在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"));
© www.soinside.com 2019 - 2024. All rights reserved.