Dlsym_c=α+βy

Dlsym_c=α+βy为什么80%的码农都做不了架构师?>>>…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

先从百度百科把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(); }

Jetbrains全家桶1年46,售后保障稳定

/************** 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函数结果如下:

092746_p7bt_1391727.png

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

093127_27KH_1391727.png

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

093443_xVra_1391727.png

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

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

转载于:https://my.oschina.net/auo/blog/315871

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215890.html原文链接:https://javaforall.net

(0)
上一篇 2025年7月12日 下午6:43
下一篇 2025年7月12日 下午7:15


相关推荐

  • pycharm双击但是无法打开的情况_mac电脑上pycharm怎么安装

    pycharm双击但是无法打开的情况_mac电脑上pycharm怎么安装本来pycharm用的好好地,电脑重启之后,突然就打不开了,双击没反应,重新安装也解决不了,百度找不到结果,就去google了。https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000120784-Can-t-open-IntelliJ-on-MacOs有兴趣的小伙伴可以看这个。主要意思就是,用命令行…

    2022年8月25日
    8
  • 请简述list,set,map类型的集合的各自特点_list与set的区别

    请简述list,set,map类型的集合的各自特点_list与set的区别List、Map、Set的区别与联系一、结构特点List和Set是存储单列数据的集合,Map是存储键值对这样的双列数据的集合;List中存储的数据是有顺序的,并且值允许重复;Map中存储的数据是无序的,它的键是不允许重复的,但是值是允许重复的;Set中存储的数据是无顺序的,并且不允许重复,但元素在集合中的位置是由元素的hashcode决定,即位置是固定的(Set集合是根据hashcod…

    2025年9月25日
    6
  • 基础知识-Java泛型擦除(简洁明了)

    基础知识-Java泛型擦除(简洁明了)0 概念 nbsp nbsp nbsp nbsp Java 泛型的参数只可以代表类 不能代表个别对象 由于 Java 泛型的类型参数之实际类型在编译时会被消除 所以无法在运行时得知其类型参数的类型 Java 编译器在编译泛型时会自动加入类型转换的编码 故运行速度不会因为使用泛型而加快 百度百科 nbsp nbsp nbsp nbsp 泛型是 JavaSE1 5 的新特性 泛型的本质是参数化类型 也就是说所操作的数据类型被指定为一个参数 这种参数类型可以用在类

    2026年3月26日
    2
  • Android—Gradle教程(九)完结篇

    Android—Gradle教程(九)完结篇前言到目前为止,Gradle基础以及Kotlin基础讲解完毕。因此,在本篇里,将会以Gradle的构建优化以及如何从Groovy迁移到KTS进行详解!话不多说,直接开始!1、Gradle构建优化优化都是些配置,快速过一下就行了!重点在迁移KTS1.1并行编译开启默认情况下Gradle处理多模块时,往往是挨个按顺序处理。在项目根目录下面的gradle.properties中设置开启并行编译,提升编译速度:org.gradle.parallel=true1.2开启编译守护进程(默认开启)

    2022年6月28日
    29
  • SCSA第四天总结「建议收藏」

    SCSA第四天总结「建议收藏」一、防共享技术:背景: 在企业的网络管理、在运营商代建的高校网络中出现了防共享上网的需求,即防代理、防一拖N的需求。 目前运营商以及企业需要面对共享上网主要带来的2个问题: 1、 在企业中,不少用户共享自己访问互联网的权限给其他用户,绕开了企业对用户设定的上网权限控制,使得原本没有上网权限的用户可以上网了,或者使得原本上网权限较低的用户拥有了较高的权限,给网络管理带来了诸多麻烦。 2、 在运营商承建和运维的高校网络中,遇到很多学生使用路由器或者其他软件方式,共享互联网的访问给其他同学或朋友,直

    2022年6月20日
    29
  • idea启动tomcat日志乱码

    idea启动tomcat日志乱码乱码样式:解决方案:如下图设置tomcat1.代码:-Dfile.encoding=UTF-82.进入设置界面:set—>editor—>fileencoding(全部设置为UTF-8)*(最重要)3.进入idea的安装文件中,bin文件下,修改idea.exe.vmoptions和idea64.exe.vmop…

    2022年6月20日
    68

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号