【问题标题】:Adding to function pointer map in dynamic library添加到动态库中的函数指针映射
【发布时间】:2013-02-11 07:24:00
【问题描述】:

下面的两个代码部分显示了重要信息。真正的工作在第三个代码段 main.cpp 中完成。

// For all files:
typedef void (*func_ptr)(Event&); // Event is a class with certain methods

foo.cpp

extern "C" void init(std::map<std::string, func_ptr> *func_ptrs)
{
    std::cout<<std::endl<<"Initializing..."<<std::endl; // does appear in output, so function does execute
    (*func_ptrs)["test"] = stuff; // the stuff function below
}

// this is the function we are trying to add to the func_ptrs map
// It looks like it's added in main.cpp, but calling it in main.cpp seg faults
void stuff(Event &e)
{
    std::cout<<"In stuff..."<<std::endl; // seg faults before this line
    // do things with e
}

main.cpp

// Excluding fluff for brevity, use comments to understand location of problem

// In main....

map<string, func_ptr> func_ptrs; // map of strings to func_ptrs
void (*init)(map<string, func_ptr>*);
// some other stuff

handle = dlopen("libfoo.so", RLTD_NOW);
// library opens successfully

*(void **) (&init) = dlsym(handle, "init"); // get the init function from the library
// No, I don't completely understand the above sequence of pointers and reference, but it does open successfully

(*init)(&func_ptrs);
// Executes successfully

// Iterating over func_ptrs shows that the new "test" mapping is in func_ptrs!!

// Next, this should call the stuff function in foo.cpp that was assigned to func_ptrs["test"]
(func_ptrs["test"])(event); // seg fault

回顾一下,

  1. libfoo.so 库正在正确加载
  2. 正在正确检索 libfoo.so 中的初始化符号
  3. 在 libfoo 的 init() 运行后,映射键“test”在 main.cpp 中可见

错误:试图执行 libfoo 的东西,位于 main.cpp 的 map func_ptrs,seg faults

注意:另一个选项可能是给 main.cpp 一个“添加到映射”函数,libfoo.so 可以调用它来将映射添加到函数列表中。这看起来更容易/更好吗?

我能够找到很多类似的问题/答案,但没有一个与我所处理的情况密切相关。非常感谢你们的帮助,我还没有失望。希望我没有搞砸缩短代码。

【问题讨论】:

  • 为简单起见,您是否尝试过打印出func_ptrs["test"] 的值?还有stuff的地址?它们匹配吗?
  • 在构建/链接 libfoo.so 时使用了哪些选项?

标签: c++ map function-pointers shared-libraries


【解决方案1】:

此代码适用于 gcc 版本 4.7.2 20121109:

d_a.cc:

#include <iostream>
#include <map>
#include <string>
#include <dlfcn.h>

class Event { 
  public: 
    void method1() { std::cout << "method1: " << name << std::endl; }
    Event(std::string& n):name(n) {}
  private: std::string name;
};
typedef void (*func_ptr)(Event&); 

int main(int argc, const char **argv) {
  std::string name = "Some";
  Event ev(name);
  std::map<std::string, func_ptr> func_ptrs; 
  void (*init)(std::map<std::string, func_ptr>*);
  void *handle = dlopen("./d_l.so", RTLD_NOW);
  *(void **) (&init) = dlsym(handle, "init");
  (*init)(&func_ptrs);
  (func_ptrs["test"])(ev);
  return 0;
}

d_l.cc:

#include <map>
#include <string>
#include <iostream>

void stuff(Event& e)
{ 
  e.method1();
  std::cout<<"In stuff..."<<std::endl; 
}

extern "C" void init(std::map<std::string, func_ptr> *func_ptrs)
{ 
  std::cout<<std::endl<<"Initializing..."<<std::endl; 
  (*func_ptrs)["test"] = stuff; 
}

编译:

g++ d_a.cc -ldl
g++ d_l.cc -fPIC -shared -o d_l.so

执行:

./a.out

输出:

Initializing...
method1: Some
In stuff...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 2011-01-09
    • 1970-01-01
    相关资源
    最近更新 更多