管理员 发布的文章

MSVC中的_BitScanForward和GCC中的__builtin_ctzl


问题

索博尔算法中用到了_BitScanForward这个函数,在做统信UOS适配的时候发现这个函数是MSVC专有的,百度了一下linux下对应的有__builtin_ctz相关的系列函数

头文件引用

*winlinux
头文件intrin.hx86intrin.h
函数_BitScanForward__builtin_ctzl

代码对比

win

  • #include <iostream>
  • #include <intrin.h>
  • using namespace std;
  • #pragma intrinsic(_BitScanForward)
  • static const unsigned QRNG_NDMS = 32;
  • struct
  • {
  • unsigned __int64 uValue;
  • unsigned uPrevSeed;
  • } m_prev[QRNG_NDMS];
  • unsigned __int64 cjn[QRNG_NDMS][63] = { 0 };
  • int main()
  • {
  • unsigned long mask = 0;
  • unsigned long index;
  • unsigned char isNonzero;
  • unsigned m_uCurSeed = 2048,m_uCurDim;
  • m_uCurDim = 0;
  • unsigned grayCode = (m_uCurSeed >> 1) ^ m_uCurSeed;
  • unsigned changedBits = m_prev[m_uCurDim].uPrevSeed ^ grayCode;
  • unsigned long uBit;
  • while (_BitScanForward(&uBit, changedBits))
  • {
  • cout << uBit << endl << changedBits <<endl;
  • m_prev[m_uCurDim].uValue ^= cjn[m_uCurDim][uBit];
  • changedBits &= ~(1 << uBit);
  • }
  • cout << uBit << endl << changedBits <<endl;
  • return 0;
  • }

Linux

  • #include <iostream>
  • #include <x86intrin.h>
  • using namespace std;
  • static const unsigned QRNG_NDMS = 32;
  • struct
  • {
  • unsigned long long uValue;
  • unsigned uPrevSeed;
  • } m_prev[QRNG_NDMS];
  • unsigned long long cjn[QRNG_NDMS][63] = { 0 };
  • int main(int, char**) {
  • unsigned long mask = 0;
  • unsigned long index = 0;
  • unsigned char isNonzero;
  • unsigned m_uCurSeed = 2048,m_uCurDim;
  • m_uCurDim = 0;
  • unsigned grayCode = (m_uCurSeed >> 1) ^ m_uCurSeed;
  • unsigned changedBits = m_prev[m_uCurDim].uPrevSeed ^ grayCode;
  • unsigned long uBit;
  • cout << __builtin_ctzl(10) << endl;
  • while (true)
  • {
  • uBit = __builtin_ctzl(changedBits);
  • if(uBit >= 64){
  • break;
  • }
  • cout << uBit << endl << changedBits <<endl;
  • m_prev[m_uCurDim].uValue ^= cjn[m_uCurDim][uBit];
  • changedBits &= ~(1 << uBit);
  • }
  • cout << uBit << endl << changedBits <<endl;
  • }

C/C++ Linux创建文件夹


描述

系统做linux适配的时候发现不能追迹,最后检查发现不能在对应目录创建相关文件夹导致的。

包含头文件

  • #include <sys/stat.h>  
  • #include <sys/types.h>

函数

函数原型:   int mkdir(const char *pathname, mode_t mode);   
函数说明:   mkdir()函数以mode方式创建一个以参数pathname命名的目录,mode定义新创建目录的权限。   
返回值:   若目录创建成功,则返回0;否则返回-1,并将错误记录到全局变量errno中。

mode模式类型:

S_IRWXU 00700权限,代表该文件所有者拥有读,写和执行操作的权限
S_IRUSR(S_IREAD) 00400权限,代表该文件所有者拥有可读的权限
S_IWUSR(S_IWRITE) 00200权限,代表该文件所有者拥有可写的权限
S_IXUSR(S_IEXEC) 00100权限,代表该文件所有者拥有执行的权限
S_IRWXG 00070权限,代表该文件用户组拥有读,写和执行操作的权限
S_IRGRP 00040权限,代表该文件用户组拥有可读的权限
S_IWGRP 00020权限,代表该文件用户组拥有可写的权限
S_IXGRP 00010权限,代表该文件用户组拥有执行的权限
S_IRWXO 00007权限,代表其他用户拥有读,写和执行操作的权限
S_IROTH 00004权限,代表其他用户拥有可读的权限
S_IWOTH 00002权限,代表其他用户拥有可写的权限
S_IXOTH 00001权限,代表其他用户拥有执行的权限

示例结果

屏幕截图 2023-03-29 071402.png


CMake: 使用install-export和find_package查找并链接到库


摘要

一个库生成后然后find_package来引用。下边的示例代码涉及到

dome代码下载

testLib.zip
GIT项目地址

库导出cmake说明

  • cmake_minimum_required(VERSION 3.5)
  • project(testLib VERSION 0.1.1 LANGUAGES C CXX)
  • set(CMAKE_INCLUDE_CURRENT_DIR ON)
  • set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/../install) # 指定安装目录
  • OPTION(BUILD_MODULE_test "test" OFF) # 设置编译子模块
  • if (NOT BUILD_LIBRARY_TYPE) # 判定是否配置生成类型下拉项
  • set (BUILD_LIBRARY_TYPE "Static" CACHE STRING "${BUILD_LIBRARY_TYPE_DESCR}" FORCE) # 设置默认类型为静态库
  • SET_PROPERTY(CACHE # 配置下拉选项
  • BUILD_LIBRARY_TYPE PROPERTY STRINGS Shared Static # 配置生成选择类型下拉项
  • )
  • endif()
  • if ("${BUILD_LIBRARY_TYPE}" STREQUAL "Shared")
  • set (BUILD_SHARED_LIBS ON) # 配置生成动态库(OFF/默认为静态库)
  • endif()
  • include_directories(include) # 添加头文件路径
  • file(GLOB FILES_SRC "src/*.cpp") # 添加当前目录下的源文件至FILES_SRC
  • add_library(${PROJECT_NAME} ${FILES_SRC})
  • ADD_CUSTOM_COMMAND( # 用于将自定义构建规则添加到生成的构建系统
  • TARGET ${PROJECT_NAME} POST_BUILD
  • COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/config $<TARGET_FILE_DIR:${PROJECT_NAME}>/config # 复制配置目录到可执行目录下
  • )
  • ############################## 安装部分 ##############################
  • TARGET_INCLUDE_DIRECTORIES( # 目标头文件搜索路径
  • ${PROJECT_NAME} PUBLIC
  • $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # 指定构建接口头文件路径, 可以add_subdirectory后直接头文件
  • $<INSTALL_INTERFACE:include> # install会自动引用include头文件
  • )
  • SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES # 设置目标的属性
  • # DEBUG_POSTFIX d # debug声称是添加d后缀
  • RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} # 二进制执行文件目录
  • ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} # 静态库目录
  • LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} # 动态库目录
  • )
  • INSTALL(
  • TARGETS ${PROJECT_NAME} # 安装目标名称
  • EXPORT ${PROJECT_NAME}Targets # 导出项目名
  • PUBLIC_HEADER DESTINATION include # 指定头文件目录
  • RUNTIME DESTINATION "bin/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>" # 二进制执行文件目录
  • ARCHIVE DESTINATION "lib/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>" # 静态库目录
  • LIBRARY DESTINATION "lib/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>" # 动态库目录
  • )
  • INSTALL(
  • DIRECTORY # 安装目录
  • include DESTINATION ${CMAKE_INSTALL_PREFIX} # 指定头文件安装目录
  • )
  • INSTALL(
  • EXPORT ${PROJECT_NAME}Targets # 导出项目名
  • FILE ${PROJECT_NAME}Targets.cmake # 生成xxxTargets.cmake文件
  • # NAMESPACE Ftest:: # 添加命名空间
  • DESTINATION cmake # 指定相对路径cmake目录
  • )
  • include (CMakePackageConfigHelpers)
  • configure_package_config_file ( # 生成 xxxConfig.cmake文件
  • cmake/Config.cmake.in ${PROJECT_NAME}Config.cmake # 根据.make.in 生成对应Config.cmake文件
  • INSTALL_DESTINATION cmake # 安装目录
  • # PATH_VARS INCLUDE_DIRS LIB_DIR
  • # INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
  • )
  • write_basic_package_version_file( # 生成 xxxConfigVersion.cmake文件
  • ${PROJECT_NAME}ConfigVersion.cmake # 指定文件名
  • VERSION ${PACKAGE_VERSION} # 指定版本号
  • COMPATIBILITY SameMajorVersion # 指定兼容性
  • )
  • INSTALL(
  • FILES
  • ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake # 复制xxxConfig.cmake文件到安装目录的cmake
  • ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake # 复制xxxConfigVersion.cmake文件到安装目录的cmake
  • DESTINATION cmake # 指定相对路径
  • )
  • INSTALL(
  • DIRECTORY
  • config/ # 复制配置文件夹
  • DESTINATION static # 指定目录
  • )

引入

直接find_package就可以直接将lib和头文件引入。

  • find_package(testLib REQUIRED)
  • target_link_libraries(${PROJECT_NAME} testLib::testLib)

使用

  • #include <iostream>
  • #include "testLib.h"
  • using namespace std;
  • int main(int, char**){
  • std::cout << "Hello, from testMain!\n";
  • auto pTestLib = make_shared<testLib>();
  • pTestLib->say();
  • }

最终调用成功!
屏幕截图 2023-06-17 090831.jpg


python: 解压缩rar


问题

所里换了台新电脑,好多环境都要重新配置,之前跟新包提交git已经脚本化,配置的那叫一个舒爽,换完电脑都要重新配置,这里记录一下过程,省着以后又得重新上网找。

下载UnRar

rar官网:点击此处访问
UnRarDLL下载:点击此处下载

安装

直接执行下载包,默认路径C:Program Files (x86)UnrarDLL,默认安装即可

添加环境变量

cmd执行(64位系统):

  • setx "UNRAR_LIB_PATH" "C:\Program Files (x86)\UnrarDLL\x64\UnRAR64.dll" /m

cmd执行(32位系统):

  • setx "UNRAR_LIB_PATH" "C:\Program Files (x86)\UnrarDLL\UnRAR.dll" /m

引号防止空格有问题,/m 指的是添加到系统变量中。

添加成功后再打开系统的环境变量如下图:
屏幕截图 2023-01-07 100420.png

python 安装 unrar

  • pip install unrar

python解压代码

  • from unrar import rarfile
  • def decompression(souce_path,target_path):
  • shutil.rmtree(target_path)
  • os.mkdir(target_path)
  • rar=rarfile.RarFile(souce_path)
  • print("开始解压文件")
  • # 判断同名文件夹是否存在,若不存在则创建同名文件夹
  • # print(os.path.splitext(souce_path))
  • if os.path.isdir(target_path):
  • rf_list = rar.namelist() # 得到压缩包里所有的文件
  • # print('rar文件内容', rf_list)
  • else:
  • os.mkdir(target_path)
  • rar.extractall(target_path) # 解压文件
  • print("文件解压成功")
  • def main(argv):
  • decompression("E:\\test.rar", "E:\\test\\")

windows: cmd下(临时set,永久setx)设置环境变量


问题

新上一批开发机,环境有些欠缺,qt、python的环境变量没有加上,需要手动设置一下。

set命令

set命令用于设置当前cmd窗口中的环境变量,只对当前cmd窗口有效,cmd窗口关闭后就没有效果了,也不会影响到系统中保存的用户环境变量。其相关用法可以百度。无参数的情况是查看变量情况。

setx命令

setx 设置永久【用户环境变量】

  • setx "name"="value" # 直接赋值(覆盖)
  • setx "name" "value" # 列表追加,键值为修改值

命令里边添加了双引号,为的是防止名称或值里有空格

setx 设置永久【系统环境变量】

  • setx "name"="value" /m
  • setx "name" "value" /m

/m 参数就是指系统环境变量

举几个例子

  • # 临时修改用户环境变量
  • set "Path"="C:\Qt\Qt5.12.11\5.12.11\msvc2017_64\bin;%path%" # 临时设置Path变量(%path%为取path值,此处可理解为向头部添加)
  • # 永久修改用户环境变量
  • setx "Path" "C:\Qt\Qt5.12.11\5.12.11\msvc2017_64\bin;" # 由于Path为列表配置项,所以是添加qt的目录值
  • setx "Path"="%path%C:\Qt\Qt5.12.11\5.12.11\msvc2017_64\bin;" # 与上一条同等效果
  • # 永久修改系统环境变量
  • setx "Path" "C:\Qt\Qt5.12.11\5.12.11\msvc2017_64\bin;" /m # 由于Path为列表配置项,所以是添加qt的目录值
  • setx "Path"="%path%C:\Qt\Qt5.12.11\5.12.11\msvc2017_64\bin;" /m # 与上一条同等效果