小编bck*_*han的帖子

为什么这个动态库加载代码与gcc一起使用?

背景:

我发现自己有一个将C++ GNU/Linux应用程序移植到Windows上的令人尴尬的任务.此应用程序执行的操作之一是在特定路径上搜索共享库,然后使用posix dlopen()和dlsym()调用动态地加载它们中的类.我们有充分的理由以这种方式加载,我不会进入这里.

问题:

要使用dlsym()或GetProcAddress()动态发现由C++编译器生成的符号,必须使用extern"C"链接块对其进行解组.例如:

#include <list>
#include <string>

using std::list;
using std::string;

extern "C" {

    list<string> get_list()
    {
        list<string> myList;
        myList.push_back("list object");
        return myList;
    }

}
Run Code Online (Sandbox Code Playgroud)

此代码是完全有效的C++,可在Linux和Windows上的众多编译器上编译和运行.但是,它不能与MSVC一起编译,因为"返回类型无效C".我们提出的解决方法是更改​​函数以返回指向列表而不是列表对象的指针:

#include <list>
#include <string>

using std::list;
using std::string;

extern "C" {

    list<string>* get_list()
    {
        list<string>* myList = new list<string>();
        myList->push_back("ptr to list");
        return myList;
    }

}
Run Code Online (Sandbox Code Playgroud)

我一直在努力为GNU/Linux加载器找到一个最佳解决方案,它既可以使用新函数也可以使用旧的遗留函数原型,或至少检测何时遇到不推荐使用的函数并发出警告.如果代码在他们尝试使用旧库时只是分段,那对我们的用户来说是不合适的.我最初的想法是在调用get_list期间设置一个SIGSEGV信号处理程序(我知道这很icky - 我对更好的想法持开放态度).所以只是为了确认加载一个旧库会发生段错误,我认为我会使用旧的函数原型(返回列表对象)通过新的加载代码(期望指向列表的指针)运行库,令我惊讶的是刚刚工作.我的问题是为什么

下面的加载代码适用于上面列出的两个函数原型.我已经确认它适用于使用gcc版本4.1.2和4.4.4的Fedora 12,RedHat 5.5和RedHawk 5.1.使用带有-shared和-fPIC的g ++编译库,并且可执行文件需要与dl(-ldl)链接.

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <list>
#include <string>

using std::list;
using std::string;

int …
Run Code Online (Sandbox Code Playgroud)

c++ gcc dlopen dlsym

7
推荐指数
1
解决办法
679
查看次数

标签 统计

c++ ×1

dlopen ×1

dlsym ×1

gcc ×1