繁体   English   中英

在共享库(Solaris,Sun Studio)中填充全局函数指针

[英]Populate global function pointers in shared library (Solaris, Sun Studio)

我正在围绕Fortran 95库创建一个小的C ++包装程序共享库。 由于Fortran符号包含. 在符号名称中,我必须使用dlsym将Fortran函数加载到C ++函数指针中。

当前,我在头文件中有一堆全局函数指针:

// test.h
extern void (*f)(int* arg);

然后将它们填充到相应的C ++文件中:

// test.cc
void (*f))(int* = reinterpret_cast<void(*)(int*>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_");

问题:

  1. 如果我这样做, 这些指针何时填充?
  2. 我可以假定它们已加载到我的可执行文件中,该可执行文件可以加载该库吗?
  3. 特别是, 可以在可执行文件或其他库中的静态创建的对象使用这些功能吗? 还是这会遭受静态初始化顺序的惨败
  4. 如果上述方法不正确, 那么填充这些指针以便可以在可执行文件和其他库中的静态对象中使用的最优雅的方法是什么?

我可以在Solaris上使用Sun Studio编译器,如果有区别的话,但是我也对Linux上的GCC解决方案感兴趣。

线在哪里

f = reinterpret_cast<void(*)(int*)>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_"));

发生在test.cc吗? 指针将在执行该行时初始化(这当然取决于何时调用包含该指针的函数)。 还是你想写

void (*f)(int* ) = reinterpret_cast<void(*)(int*>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_");

在这种情况下,指针将在静态初始化期间初始化。 这意味着,如果您尝试在静态对象的构造函数中使用指针,则仍然存在初始化问题的顺序。

对此的经典解决方案是使用某种单例:

struct LibraryPointers
{
    void (*f)(int* );
    //  ...
    static LibraryPointers const& instance()
private:
    LibraryPointers();
};

LibraryPointers const&
LibraryPointers::instance()
{
    static LibraryPointers theOneAndOnly;
    return theOneAndOnly;
}

LibraryPointers::LibraryPointers()
    : f( reinterpret_cast<void(*)(int*)>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_")) )
    , //  initialization of other pointers...
{
}

然后将库包装在一个C ++类中,该类使用此结构来获取指针的地址。

最后一句话:您尝试执行的reinterpret_cast非法,至少在形式上不合法。 (但是,我认为Sun CC和g ++都会接受它。)根据Posix的说法,从dlsym获取指向函数的指针的正确方法是:

void (*f)(int* );
*reinterpret_cast<void**>(&f) = dlsym(...);

但是,这并不适合进行初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM