如何从 Linux 上的动态库加载静态函数(在 C 中)

Nil*_*ile 1 c c++ static function

我在动态库傻瓜中有一个静态函数“foo”。我成功地在我的应用程序中加载了傻瓜。尽管 dlsym 为“foo”返回 NULL

甚至 nm 实用程序也没有将静态函数列为可导出符号。

我知道静态函数的范围仅限于该文件。

不过,有没有办法实现这一点。

我知道这在 C++ 中是可能的,不知道如何以及为什么(可能共享库被视为对象,该库中的函数被视为接口。)

Mat*_*lia 5

static不仅仅是一个“作用域”——static函数有内部链接,所以编译器不会在目标文件中写入关于它们存在的信息;此类信息以后无法恢复(在创建​​动态库时)。

更好的是:如果它是一个小函数,它可能在任何情况下都会被内联,并且由于它具有内部链接,因此不需要生成“独立”版本,因此在编译阶段之后该函数实际上将不再存在.

我认为“从外部”获取此类函数的地址的唯一实用方法是在同一个翻译单元(即在同一个 .cpp 文件中)使用另一个函数,该函数返回指向该foo函数的指针,然后导出这样的辅助功能。可行,但如果你问我,那就毫无意义了。:)


// In foolib

// The static function
static void foo()
{
    // ...
}

// Typedef for the function pointer
typedef void (* fooFuncPtr)();

// Helper function to be exported - returns the address of foo
fooFuncPtr fooHelper()
{
    return &foo;
}
Run Code Online (Sandbox Code Playgroud)
typedef void (* fooFuncPtr)();
typedef fooFuncPtr (* fooHelperFuncPtr)();

// In the client code of foolib
// ...
fooHelperFuncPtr fooHelper = (fooHelperFuncPtr) dlsym(handle, "fooHelper");
// ... in real code here you would have error checking ...
fooFuncPtr foo = fooHelper();
// now you can use foo
foo();
Run Code Online (Sandbox Code Playgroud)