2018年1月

c++类函数编译链接问题

1. 缘由

由于前段时间遇到类外定义函数出现链接错误,而类内定义却链接成功,所以花了点时间从汇编角度来分析c++类函数编译链接问题

2. 对函数的理解

可能很多人对类函数和全局函数的理解不够深刻,所以先简单说明一下。从机器语言角度理解,函数本质上就是代码区的地址,所以无论全局还是类函数都仅是一个地址而已。C全局函数用函数名唯一标记这个地址,C++全局函数用函数名和参数类型名来唯一标记,而C++类函数则用类名、函数名、参数类型名来唯一标记,所以C++有面向对象、同名函数可重载等特性。事实上,类静态函数和非静态函数的调用机制本质上都是函数的调用机制,参数进栈->跳转至函数地址->局部变量进栈->函数逻辑->局部变量出栈->参数出栈->返回调用前地址,对于非静态函数,无非把类对象本身作为入栈参数传递给函数,所以类非静态函数至少有一个参数入栈,以下是类非静态函数的反汇编

图一.jpg

3. 函数在类内定义和类外定义区别

很多人甚至很多权威书籍认为类内定义的函数属于内联函数,事实上并非如此,若编译时采用默认优化选项(O=0),则不属于内联函数,只有设置优化选项(O>=1),类内定义的函数才是内联的,而类外定义的函数,除非加上inline关键字,否则始终不是内联函数,以下是类内定义函数的反汇编

图二.jpg

4. 链接器对函数的处理

若a.h中定义一个函数,b.cpp和c.cpp均包含a.h,则链接时会提示函数重复定义。同样若在a.h中定义一个类,并在类外部定义一个函数,则链接同样会提示函数重复定义,但在类内部定义一个函数,则链接不会报错。很多人认为在类内部定义函数被内联了,当然不会报错,但事实不然,若此时采用默认优化选项(O=0),同样也不会报错。学过汇编的都应该知道,代码区是分节的,通常代码区首节是.init用于进程初始化,我们写的代码基本都在.text节,通过对b.o和c.o进行反汇编发现,全局函数和类外定义的函数均在.text节,而类内定义的函数则在.text.fun节,fun为函数名。因此对于全局和类外定义的函数而言,都在.text节,链接器在合并.text内的代码时,当然会报函数重复定义,而对于类内定义的函数而言,在.text.fun节中,链接器首先把b.o中.text.fun节合并到.text,之后在合并c.o中.text.fun节时,发现已经合并过了,则会跳过,当然就不会报函数重复定义。对于模板函数就更特殊了,无论是全局模板函数还是在类内部或外部定义的模板函数,编译器均会给模板函数分配代码节.text.fun,因此模板函数不存在链接时重复定义问题。以下是类内和类外定义函数的反汇编

图三.jpg

vmware-kvm.exe 管理虚拟机

1. windows开机自启动linux虚拟机

vmware-kvm.exe ubuntu-serv.vmx
把此脚本放在B:\Windows\System32\GroupPolicy\User\Scripts\Logon

2. windows关机自挂起linux虚拟机

vmware-kvm.exe --suspend ubuntu-serv.vmx
把此脚本放在B:\Windows\System32\GroupPolicy\User\Scripts\Logoff

Python MySQLdb 模块安装

1. 安装python

  • 下载源码(version>=2.3.4)

    https://www.python.org/downloads/source/

  • 编译安装

    CFLAGS="-O3 -fPIC" ./configure
    make && make install

2. 安装setuptools

  • 下载和python版本一致的egg

    https://pypi.python.org/pypi/setuptools/0.6c11

  • 执行egg

    chmod a+x setuptools-0.6c11-py2.7.egg
    sh ./setuptools-0.6c11-py2.7.egg

3. 安装MySQL-python

  • 下载源码

    https://pypi.python.org/pypi/MySQL-python/

  • 编译安装

    C_INCLUDE_PATH=/usr/local/include/python2.7
    export C_INCLUDE_PATH
    python setup.py build
    python setup.py.install

  • 验证

    python -c "import MySQLdb" && echo $?
    若上述命令返回0,则表明MySQLdb安装成功

读书计划

1. 计算机专业书籍

《算法导论》、《TCP/IP详解》、《网络游戏核心技术与实战》,若还有时间,再看AI方面的书籍

2. 文学类书籍

《三体》