两个知识点的回顾(const指针和动态链接库函数dlopen)
昨天,看了一点《c++ primer》和《程序员的自我修养》,想起了自己以前的两个知识点,这里回顾,并且总结一下。
1. const指针的参数
看primer的时候,看到几个概念,虽然都大概知道,但是还是有点模糊的,今天权且记在这里。
(1)const形参
const形参,从const的意思来看,就是形参是const的,不能够改变。但是函数在传值的时候都是传的副本,所以不管形参是不是const,都可以使用const或者非const的实参传递。【注:这里指的是普通的形参】
(2)const引用避免复制
这个是之前不理解的,在c++中,const的引用是不会发生复制行为的,这样在大类型为参数的时候,节省了复制的时间,提高了效率。
(3)非const的引用不灵活
因为形参是非const,这样导致传进来的的参数必须是非const,从而字符串常量已经const的参数就导致编译错误了。
(4)总结
看到这里的时候,想起以前面试的时候一道题:
char str1[] = "string";
char *str2 = "string";
testfunc1(char *str1)
testfunc2(const char*str),问下面表达式的对与错,
*testfunc1(str1)
*testfunc1(str2)
*testfunc2(str1)
*testfunc2(str2)
解释:
str1是一个字符数值,也可以理解为c风格的字符串(针对c++),大小为7,包括最后的'\0'。
str2是一个指向const类型的字符串的指针,大小也是7,不能修改了。
testfunc1的形参是一个非const的字符串指针
testfunc2的形参是一个指向const字符串的指针,在函数体能不能修改str的值。这只是表示不能在函数中对str修改。
所以从const的意义上,我给出的答案是
*testfunc1(str1) Y
*testfunc1(str2) N 函数体内是可以修改str2的,但是str2是const,不能被修改。
*testfunc2(str1) Y
*testfunc2(str2) Y
2. 动态链接库的接口函数使用
(1)书上代码分析
#include <stdio.h>
#include <dlfcn.h> #define SETUP_STACK \
i = 2; \
while (++i < argc - 1) { \
printf("i: %d\n", i);\
switch (argv[i][0]) { \
case 'i': \
printf("%d\n", i);\
asm volatile("push %0" :: \
"r"(atoi(&argv[i][1])) ); \
esp += 4; \
printf("%d\n", i);\
break; \
case 'd': \
atof(&argv[i][1]); \
asm volatile("subl $8, %esp\n" \
"fstpl (%esp)" ); \
esp += 8; \
break; \
case 's': \
asm volatile("push %0" :: \
"r"(&argv[i][1]) ); \
esp += 4; \
break; \
default: \
printf("error argument type"); \
goto exit_runso; \
} \
printf("%d\n", i);\
} #define RESOTRE_STACK \
asm volatile("add %0, %%esp"::"r"(esp)) int main(int argc, char* argv[])
{
void *handle;
char *error;
int i;
int esp = 0;
void *func; handle = dlopen(argv[1], RTLD_NOW);
if(0 == handle)
{
printf("Can't find library: %s\n", argv[1]);
return -1;
} func = dlsym(handle, argv[2]);
if ((error = dlerror()) != NULL)
{
printf("Find symbol %s error: %s\n", argv[2], error);
goto exit_runso;
} switch (argv[argc - 1][0])
{
case 'i':
{
int (*func_int)() = func;
SETUP_STACK;
printf("%p\n", func_int);
int ret = func_int();
RESOTRE_STACK;
printf("ret = %d\n", ret);
break;
}
case 'd':
{
double (*func_double)() = func;
SETUP_STACK;
double ret = func_double();
RESOTRE_STACK;
printf("ret = %f\n", ret);
break;
}
case 's':
{
char* (*func_str)() = func;
SETUP_STACK;
char *ret = func_str();
RESOTRE_STACK;
printf("ret = %s\n", ret);
break;
}
case 'v':
{
void (*func_void)() = func;
SETUP_STACK;
func_void();
RESOTRE_STACK;
printf("ret = void");
break;
}
}/* end of switch */ exit_runso:
dlclose(handle);
}
后面比较简单,前面的汇编代码没怎么看懂,再研究一下。
(2)回顾自己之前的代码
void prepare_start_dark(){
/* 调入动态函数分析 */
handle=dlopen("./lxx.so",RTLD_LAZY);//open lib file
if(handle == NULL){
printf("Warning: no lib file, program go on!\n");
daylog_error("Warning: no lib file, program go on!\n");
get_xx = get_xx_default;
}
else{
get_xx = dlsym(handle,"get_xx");//call dlsym function
}
} void prepare_end_dark(){
/* */
if(handle != NULL)
dlclose(handle);
}
感觉之前写的还是比较正常的,唯一不一样的是用了RTLD_LASY,应该是查资料的时候,别人这样用的,就直接copy过来的。看了书之后,知道是延迟绑定,就是动态链接器启动加载的时候并不是把所有的共享对象都加载进去,而是加载一部分需要的,这样提高了程序启动时候的性能。延迟绑定就是第一次用到的时候在加载!
(3)总结
还是有点为了学习而学习的感觉,上面的汇编代码一定要去学习看明白!
两个知识点的回顾(const指针和动态链接库函数dlopen)的更多相关文章
- const 指针与指向const的指针
最近在复习C++,指针这块真的是重难点,很久了也没有去理会,今晚好好总结一下const指针,好久没有写过博客了,记录一下~ const指针的定义: const指针是指针变量的值一经初始化,就不可以改变 ...
- void指针和const指针
void指针:主要是便于传递不同类型的参数 const指针: const char *p :const 在* 的左边表示指向一个常量指针:表示指向的内容不可变(*p不能变,p可以改变) int a = ...
- const 指针
使用指针时要涉及两个目标,即指针本身和指针所指的对象.关于const指针变量,可归结为以下三种: 1.指向常量的指针变量: 2.常指针变量: 3.指向常量的常指针变量. 一.指向常量的指针变量:声明格 ...
- C++的引用与const指针的关系以及各种传递方式
首先我们知道 const int *p 与 int const *p 是一样的,即 *p 是常量:而 int * const p 跟上面是不一样的,即 p 是常量:我们知道引用只是一个别名,与变量共享 ...
- 速记const 指针与指向const的指针
指向const的指针.它的意思是指针指向的内容是不能被改动的.它有两种写法. ` const int* p; (推荐) int const* p;` 再说const指针.它的意思是指针本身的值是不能被 ...
- const指针与指向const的指针
当使用带有const的指针时其实有两种意思.一种指的是你不能修改指针本身的内容,另一种指的是你不能修改指针指向的内容.听起来有点混淆一会放个例子上来就明白了. 先说指向const的指针,它 ...
- const指针总结
const 总结: 假设keywordconst出如今星号左边.表示被指物是常量:即不能通过指针改动变量的值. 假设keywordconst出如今星号右边,表示指针自身是常量:即不能改变指针的指向. ...
- C++之常指针,指针常量,函数指针,const用法总结
1.const char *p,char const *p,char * const p 对于C++而言,没有const * 修饰符,所以,const只可以修饰类型或者变量名.因而const char ...
- 函数返回值为 const 指针、const 引用
函数返回值为 const 指针,可以使得外部在得到这个指针后,不能修改其指向的内容.返回值为 const 引用同理. class CString { private: char* str; publi ...
随机推荐
- Android Notification 的四种使用方式
实现通知步骤 一般实现通知需要如下步骤: 1.获取 NotificationManager 实例管理通知: 2.实例 Notification 对象: 3.管理事件 Intent: 4.发送通知. 注 ...
- Revit二次开发_快速显示隐藏剖面框
最近遇到一种状况需要经常切换剖面框的可见性,于是想将剖面框的显示与隐藏做成一个按钮,方便切换. 其他类似元素想做成快速切换可见性应该可以使用类似做法. 这次的隐藏对象是剖面框,所以我直接就隐藏元素了. ...
- pxe-kickstart
PXE client--->DHCP(pxelinux.0; next-server tftp-server) syslinux vmlinuz initrd.img ks.cfg--- ...
- selenium+JDBC实现参数自动化测试
测试模拟环境:在www.1905.com网站中执行两个用户的登陆退出操作 需要的文件有: 1.User的实例类: public class User { private String username ...
- Cloudera Manager安装之Cloudera Manager安装前准备(Ubuntu14.04)(一)
其实,基本思路跟如下差不多,我就不多详细说了,贴出主要图. 博主,我是直接借鉴下面这位博主,来进行安装的!(灰常感谢他们!) 在线和离线安装Cloudera CDH 5.6.0 Cloudera M ...
- 更新jdk后 Light Table无法找到新版本jdk的bin目录
原来是lein构建工具中保存了原来jdk版本记录,就是这个profiles文件 原来jdk1.7.0_17 我现在改成如下图jdk1.7.0_40 问题解决
- oracle中斜杠(/)的含义
斜杠就是让服务器执行前面所写的sql脚本.如果是普通的select语句,一个分号,就可以执行了.但是如果是存储过程,那么遇到分号,就不能马上执行了.这个时候,就需要通过斜杠(/)来执行. 1 2 3 ...
- 2-3 树/红黑树(red-black tree)
2-3 tree 2-3树节点: null节点,null节点到根节点的距离都是相同的,所以2-3数是平衡树 2叉节点,有两个分树,节点中有一个元素,左树元素更小,右树元素节点更大 3叉节点,有三个子树 ...
- ASP.NET Core中使用默认MVC路由
ASP.NET Core里Route这块的改动不大,只是一些用法上有了调整,提供了一些更加简洁的语法. 而对于自定义路由的支持当然也是没有问题的,这个功能应该是从MVC1.0版本就已经有这个功能. 先 ...
- vue(2.0)+vue-router(2.0)+vuex(2.0)实战
好久没更新自己的知识库,刚好借双十一的契机,用上了vue(2.0)+vue-router(2.0)+vuex(2.0)来开发公司的双十一电商活动. 项目目录结构: 运行: npm install np ...