标签:cpp

以下是与标签 “cpp” 相关联的文章

MINGW 和 jni 相关几个问题

生成 jni 头文件方法

# file: src/com/litchi/HelloWord.java
cd src
javah com/litchi/HelloWorld

MINGW 编译 jni 无法被 java 加载问题

因为 dll 中导出的函数签名与 VC 生成的不一致。需要加上编译参数

-Wl,--add-stdcall-alias

用 strip 减小可执行文件大小

动态库 *.so *.dll

可以删除所有符号

strip -s *.so 

静态库 *.a

只能删除调试符号

strp -g --strip-unneeded *.a

windows 下安装 clang4.0

  • 下载 llvm4.0-win32 ,安装到 D:/llvm32
  • 下载 mingw-get , 安装到 D:/MinGW
  • D:/llvm32/bin D:/MinGW/bin 添加到 PATH 变量
  • 添加下列环境变量

    CC=clang
    CXX=clang++
    CFLAGS=-target i686-pc-windows-gnu
    CXXFLAGS=-target i686-pc-windows-gnu
    
  • clang3.7 版本之前,不需要设置 CFLAGS CXXFLAGS 编译目标,因为 windows 下仅支持 MinGW 编译工具;clang3.8 版本之后,需要设置编译目标,因为可以支持 MSVC 编译工具,默认编译目标是 i686-pc-windows-msvc
  • 如果需要 64 位编译环境,则 llvm 和 mingw 都要安装 64 位版本的。
  • 如果是 64 位系统,可以直接安装 llvm 64 位,兼容编译 32 位和 64 位程序

GCC 多个 lib 同名函数链接冲突问题

问题描述

  • 用 gcc 编译两个动态库 lib1.so lib2.so, 程序 app 链接到这两个动态库
  • lib1.so 中定义了全局变量 var=1 , lib2.so 中定义全局变量 var=2 。即相同变量 var 在不同 lib 中定义值不同。
  • lib1.so 中定义了函数 fun1() { print(var); }
  • lib2.so 中定义了函数 fun2() { func1(); print(var); } , 即 lib2.so 依赖 lib1.so
  • 运行 app,调用 fun1fun2 ,输出 var 的值是相同的。

问题分析

  • gcc 链接时,有个默认规则:当一个符号需要被加入全局符号表时,如果相同的符号名已经存在,则后加入的符号被忽略
  • 用 VC 编译链接这个程序, fun1fun2 会输出不同值: VC 在发现多个依赖库中有同名符号时, 会符号重定义, 而不是默认的选择一个

问题解决

  • 使用编译参数 -fvisibility=hidden ,使所有符号默认不导出
  • 将 fun1 和 fun2 声明为导出符号

    #define MY_API __attribute__((visibility("default")))
    void MY_API fun1();
    void MY_API fun2();
    
  • fun1fun2 可以输出各自 lib 中定义的值。

在 ubuntu server 上搭建 C++ 远程开发环境

  • 安装开发软件

    apt install build-essential
    apt install clang
    apt install cmake
    apt install git
    apt install subversion
    apt install ninja ninja-build
    apt install gcc-multilib g++-multilib lib32z1-dev
    
  • 安装并配置 samba

    apt install samba
    apt install smbclient
    cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
    
    emacs /etc/samba/smb.conf
    
    [share]
      comment = Share Folder require password
      browseable = yes
      path = /home/share
      create mask = 0777
      directory mask = 0777
      valid users = share
      force user = nobody
      force group = nogroup
      public = yes
      writable = yes
      available = yes
    
    groupadd share -g 6000
    useradd share -u 6000 -g 6000 -s /sbin/nologin -d /dev/null
    smbpasswd -a share
    
    mkdir /home/share
    chmod 777 /home/share
    /etc/init.d/smbd restart
    

C++ do’s and don’ts

do’s

  • 头文件中尽量使用前置声明
  • 可继承类的析构函数一定是虚函数

don’ts

  • 构造函数中不能调用虚函数