2016-11-22 61 views
1

我需要从使用C++的Solaris 10上的当前可执行文件中知道函数地址(我正在使用GNU g ++ 4.9.2)。例如,我有一个函数说:void doSomething(const char * p),它可能会或可能不会在当前的可执行文件中定义。所以,我想搜索当前可执行文件中的函数(如果存在),然后调用该函数执行一些默认操作。我怎么做? dlsym会帮忙吗? 请帮助我的语法和损坏的名称。如何从当前可执行文件获取函数地址?

+0

是的,这正是dlsym的目的。它将通过(错位)名称返回函数的函数指针(即地址)。 – Cameron

+0

@Cameron请帮我使用参数(从当前可执行文件搜索)以及损坏的名称 –

回答

3

您可以通过运行nm exec来获取可执行文件中的符号列表。或者,如果您尝试从共享库中获取符号,则也可以使用符号库。挑选你想要的,并且用类似加载...

void* handle = dlopen(NULL, RTLD_LAZY); 
void* ptr = dlsym(handle, "mangled_name_you_got_from_nm"); 

虽然你可能会想将它转换为函数指针类型,你是通过什么样加载(显然,改变了功能合适的函数指针类型)...

void* handle = dlopen(NULL, RTLD_LAZY); 
auto ptr = reinterpret_cast<int(*)(int)>(dlsym(handle, "mangled_name_you_got_from_nm")); 
+0

在Solaris 10上是否有等价的nm?这将帮助我得到损坏的名称 –

+0

您可以使用[elfdump -S](https://docs.oracle.com/cd/E26502_01/html/E29030/elfdump-1.html#REFMAN1elfdump-1) – yugr

+0

This答案存在两个缺陷:(1)编译器之间或甚至同一编译器的不同版本之间的名称修改可能会改变。 (2)除非主要的可执行文件与'-rdynamic'(或等价的)链接,否则该函数将不会被导出到动态符号表中,并且'dlsym'将返回NULL。 –

0

需要“叫foo()如果它被定义,但什么都不做,如果它不是”是图书馆相当普遍。

一个常见的例子是如果程序与线程链接,则调用pthread_mutex_lockpthread_mutex_unlock,否则不执行锁定。

微弱的未解决的符号是一个完美的解决方案。

extern void foo() __attribute__((weak)); 

void MaybeCallFoo() 
{ 
    if (&foo == NULL) { printf("foo is not defined\n"); return; } 
    foo(); // It is defined, call it. 
} 
相关问题