文档章节

dlsym与C++

enimey
 enimey
发布于 2014/09/19 09:44
字数 627
阅读 478
收藏 0

先从百度百科把dlsym的简介拉过来:

功能:根据动态链接库操作句柄与符号,返回符号对应的地址;

函数定义:void*dlsym(void*handle,constchar*symbol);

函数描述:dlsym(dynamic library symbol) 根据 动态链接库 操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。 handle:由dlopen打开动态链接库后返回的指针; symbol:要求获取的函数或全局变量的名称。 返回值: void* 指向函数的地址,供调用使用。

现在来看三个示例,main.c、test_C.c、test_C++.cpp:

/**************
main.c
gcc main.c -ldl -o main
**************/
#include <stdio.h>
#include <dlfcn.h>

void main() {
	void *handle;
	void(*test)();
	handle = dlopen("/home/auo/Study/C/name mangling/libtest_C.so", RTLD_NOW);
	if(!handle)
		return -1;
	test = (void(*)())dlsym(handle, "test");
	printf("test in C addr:\t%x\n", test);
	test();


	handle = dlopen("/home/auo/Study/C/name mangling/libtest_C++.so", RTLD_NOW);
	if(!handle)
		return -1;
	test = (void(*)())dlsym(handle, "test");
	printf("test in C++ addr:\t%x\n", test);
	test();
}

/**************
test_C.c
gcc test_C.c -fPIC -shared -o libtest_C.so
**************/
#include <stdio.h>

void test() {
	printf("Call test in C\n");
}

/**************
test_C++.cpp
g++ test_C++.cpp -fPIC -shared -o libtest_C++.so
**************/
#include <stdio.h>

void test() {
	printf("Call test in C++\n");
}

编译完成后得到可执行程序main,动态库文件libtest_C.so、libtest_C++.sp。在终端执行main函数结果如下:

dlsym函数并没有成功找到由g++编译后的libtest_C++.so里的函数test的地址,我们知道dlsym函数是通过查找指定动态库中的符号表来获得符号地址的,我们现在用readelf查看下libtest_C++.so的符号表:

清楚的看到并没有符号test的信息,而只有_Z4testv的符号信息,所以当dlsym查找符号test的时候自然就返回0了。我们再看一下libtest_C.so的符号表:

可以看到libtest_C.so符号表是存在test符号的。

那么,为什么g++编译器会将符号test更名为_Z4testv呢,这个就是因为name mangling机制。具体来讲就是因为C++存在函数重载,C++编译器在编译的时候会根据一个函数的名字、参数、返回值来生产一个独一无二的符号名字,这样才Link的时候,才能区分出不同的函数。extern "C" void test()可以避免name mangling(事实上,就是告诉编译器这个函数按照C的规则进行编译,自然就不会发生name mangling)。

© 著作权归作者所有

enimey
粉丝 13
博文 18
码字总数 12299
作品 0
成都
私信 提问
使用dlopen和dlsym来使用C++中的类

使用dlopen和dlsym来使用C++中的类 2008-08-09 23:43:37 分类: 一般来说,dlopen和dlsym是来处理C库中的函数的,对于C++中存在的name mangle问题,类的问题就不易处理,看下文你会有所收获。...

秋天的胡杨
2014/03/03
2.4K
2
Lua调用c++模块

我将c++的一些供Lua调用的函数写到了一个模块中,代码如下。 我把这些函数封装到了模块tt中,然后使用g++进行了编译,打包出来一个libtt.so共享库,然后我配置了一下LUA_CPATH的环境变量,将...

小塔_皂荚花
2014/09/19
1K
5
linux下C++ 插件(plugin)实现技术

linux下C++ 插件(plugin)实现技术 作者:掌门狗 时间:2008-12-01 20:21 分类:默认分类 标签: c++ 插件 应用程序中使用插件技术,有利于日后的版本更新、维护(比如打补丁)和功能扩展...

秋天的胡杨
2014/03/03
1K
0
Android多媒体开发-- android中OpenMax的实现整体框架

原址 1.android中用openmax来干啥? android中的 AwesomePlayer就 是用openmax来做(code)编解码,其实在openmax接口设计中,他不光能用来当编解码。通过他的组件可以组成一个完整的播放器,包...

慢慢的燃烧
2018/09/03
0
0
QtInternal 之 Plugin

注意:本文翻译自 http://developer.qt.nokia.com 中的BasicsOfPlugins 与QtPlugin ,中文译文见 插件基础 与 插件 ,如果你对翻译wiki感兴趣,请参考Wiki中文帮助 注:QtInternal 系列是用来...

晨曦之光
2012/05/08
86
0

没有更多内容

加载失败,请刷新页面

加载更多

一起来学Java8(三)——方法引用

在一起来学Java8(一)——函数式编程中有一个简单的函数式编程的例子: import java.util.function.Consumer;class Person { public static void sayHello(String name) { S...

猿敲月下码
3分钟前
0
0
读书笔记:深入理解ES6(十一)

第十一章 Promise与异步编程   Promise可以实现其他语言中类似Future和Deferred一样的功能,是另一种异步编程的选择,它既可以像事件和回调函数一样指定稍后执行的代码,也可以明确指示代码...

张森ZS
26分钟前
7
0
面试官,Java8 JVM内存结构变了,永久代到元空间

在文章《JVM之内存结构详解》中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化。作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试...

程序新视界
34分钟前
23
0
Elasticsearch 实战(一) - 简介

官腔 Elasticsearch,分布式,高性能,高可用,可伸缩的搜索和分析系统 基本等于没说,咱们慢慢看 1 概述 百度:我们比如说想找寻任何的信息的时候,就会上百度去搜索一下,比如说找一部自己喜...

JavaEdge
39分钟前
16
0
【jQuery基础学习】11 jQuery性能简单优化

本文转载于:专业的前端网站➦【jQuery基础学习】11 jQuery性能简单优化 关于性能优化 合适的选择器 $("#id")会直接调用底层方法,所以这是最快的。如果这样不能直接找到,也可以用find方法继...

前端老手
48分钟前
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部