openharmony 南向开发基础:ohos自定义子系统,自定义部件,调用hilog部件,hilog日志封装傻瓜式教程

openharmony 南向开发基础:ohos自定义子系统,自定义部件,调用hilog部件,hilog日志封装

自定义单部件

关于开源鸿蒙的南向教程不多,很多都是从官方文档上抄的的例子,官网的例子不是很适合入门,写的很粗糙,不适合傻瓜阅读,毕竟对于刚入行鸿蒙的新手而言,gn语法就是第一劝退魔咒,且openharmony使用的是ohos自定义gn模板,想先自学gn语法再学鸿蒙的话那得猴年马月了,说一千道一万不如实战干一干,会不会骑马你先找匹马上了再说,摔不死就会了
下面给出官网范例以及相应的视频讲解

  1. 官网文档subsys-build-component.md
  2. 视频讲解

看完上面的视频聪明的你应该能抄出一个应用程序,一个动态库,并且使用应用程序引用动态库
上面的例子基于同一个部件,应用程序跟动态库属于同一部件的两个模块,动态库的调用属于部件内调用
上面例子的局限在于,动态库(so库)没有导出部件间接口,即动态库跟exe同属一个部件,其他部件无法使用ohos推荐的gn语法调用so库,但是可以用传统意义上的C++编译规则,获取编译生成的so库和头文件加入到你的部件中,进行手动链接

自定义多部件

为了客服上述单部件创建的so库无法被另一部件gn模板调用的问题,本章节讲解如何使用部件间依赖
首先用白话描述下几个关键名词

  1. 子系统:子系统是一个逻辑上的概念,是鸿蒙模块化构建的第一层,由若干个部件组成,在形式上表现为一个子系统文件夹内部有多个部件文件夹,子系统目录的位置一般为源码根目录,在//build/subsystem_config.json 中可以增删编辑你需要的子系统
  2. 部件:部件是一个构建上的概念,在构建的时候需要提供部件的标志性文件bundle.json,即哪个文件夹内有一个bundle.json就表示这个文件夹内定义了一个部件
  3. 模块:模块是更细层面的构建概念,一个部件由若干个模块组成,每个模块在gn构建语法中体现为一个构建目标target

构建流程

构建的命令形如: ./build.sh --product-name 产品名 --ccache --no-prebuilt-sdk
在使用命令进行源码构建的时候会读取//build/subsystem_config.json中的配置(//表示源码根目录),只有在该文件中配置的子系统才会参与构建,构建的命令中出现了产品名,说明会读取//vendor目录下指定产品的config.json文件,该文件中指明了产品需要的子系统中的那些部件,因此想自定义一个部件参与编译至少需要三步

  1. //build/subsystem_config.json中添加子系统
  2. config.json中添加待编译的子系统部件
  3. 创建自定义部件

创建部件

首先在源码根目录下创建一个文件夹作为逻辑上的子系统,如这里创建一个文件夹为sample,路径为 //sample 即跟//build目录同级
在sample文件夹下创建三个目录:hello , self_share , self_static,分别表示三个部件
hello文件夹是exe部件,self_share是so库部件,self_static是a库部件
参照上面视频教程中的目录结构,在三个目录中分别创建如下结构目录
sample
| ____hello
| ____|____include
| ____| ____|____helloworld.h
| ____| ____|____selfhilog.h
| ____|____src
| ____| ____|____helloworld.cpp
| ____|____BUILD.gn
| ____|____bundle.json
|
| ____self_share
| ____|____include
| ____| ______|____selfshare.h
| ____|
| ____|____src
| ____| _____|____selfshare.cpp
| ____|____BUILD.gn
| ____|____bundle.json
|
| ____self_static
| ____|____include
| ____| ______|____selfshare.h
| ____|
| ____|____src
| ____| ____|____selfshare.cpp
| ____|____BUILD.gn
| ____|____bundle.json
根据目录很清晰可知,hello , self_share , self_static三个目录下均有bundle.json文件,表示这三个目录分别定义了三个部件

  1. 为什么要定义成部件呢?
    在鸿蒙南向开发中,最基本的技能就是掌握部件的构建以及部件相互之间的调用,开发中的难点是如何理解部件并调用开源代码中的系统部件,为了便于快速上手,本范例提供了系统部件hilog调用,自定义一个自动安装的系统部件,一个so库部件模板,一个a库部件模板.
  2. a库(静态库)为什么要定义成部件呢?
    从正式开发上来说,a库一般作为部件内模块,不会单独作为部件提供,因为a库的特性从本质上讲就是源码,编译链接期间会编译进宿主程序,一般会把common,utils等工具类公共类的代码编译为a库,供同部件下其他程序链接使用,但是作为练习教程来讲,C++的三板斧,exe,so,a不能不讲
hello部件

hello部件作为最基础全面的入门部件,本范例提供的hello部件拥有如下功能:

  • 基本的exe部件构建
  • 调用系统部件hilog,封装hilog日志打印
  • 调用self_share部件so库
  • 调用self_static部件a库
基本的exe部件构建

构建一个exe部件的最基础文件为一个.h,一个.cpp,一个.gn,一个.json,上述目录中的selfhilog.h是封装的hilog,本节暂且不提
.h文件如下:

#ifndef HELLOWORLD_H
#define HELLOWORLD_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
void HelloPrint();
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif  // HELLOWORLD_H

.cpp文件如下:

#include <stdio.h>
#include "helloworld.h"
int main(int argc, char ** argv) {
    HelloPrint();
    return 0;
}
void HelloPrint() {
    printf("\n\n##################################");
    printf("\n\tHello G!\n");
    printf("\n\n----------------------------------\n");
}

.gn文件内容如下:

import("//build/ohos.gni")   #导入编译模板
ohos_executable("helloworld") {  #可执行模块
    sources = [   #模块源码
        "src/helloworld.cpp"
    ]
    include_dirs = [ #模块依赖头文件目录
        "include"
    ]
    cflags = []
    cflags_c = []
    cflags_cc = []
    ldflags = []
    configs = []
    deps = []             #部件内部依赖
    external_deps = []    #部件间依赖
    part_name = "hello"   #所属部件名称,必选
    install_enable = true #是否默认安装(缺省默认不安装),可选
}

.json文件内容如下:

{
    "name": "@ohos/hello",		                     
    "description": "Hello world example",		               
    "version": "3.1.0",			                          
    "license": "Apache License 2.0",			          
    "publishAs": "code-segment",		                    
    "segment": {				
        "destPath": "sample/hello"
    },					                                      
    "dirs": {},	               
    "scripts": {},			                                 
    "component": {			                                 
        "name": "hello",			                    
        "subsystem": "sample",		                            
        "syscap": [],				                        
        "features": [],                                      
        "adapted_system_type": ["standard"],		                    
        "rom": "",                                       
        "ram": "",                                       
        "deps": {          
        "components": [],
        "third_party": []
      },  
        "build": {				                            
            "sub_component": [
                "//sample/hello:helloworld" 
            ],			                                  
            "inner_kits": [],						     
            "test": []							     
        }
    }
 }

.h跟.ccp文件太基础了就不提了,.gn文件跟.json文件是重点
gn文件描述的是编译的最小target,也就是上面说的模块,gn里面使用了ohos的自定义模板ohos_executable;该函数表示构建一个exe程序,gn文件中最重要的是part_name,该字段表示整个gn文件中的模块属于哪一个部件
json文件描述的是一个部件,segment -> destPath写入你的部件源码目录, component-> name 写入你的部件名字,component-> subsystem 写入当前部件所属的子系统,上面讲了,一个部件可以拥有若干个子模块,如何表示若干个子模块呢?在build->sub_component 中加入你的部件拥有的子模块 形如 子部件目录d:模块名字name,编译的时候会去子部件目录d寻找gn文件,去gn文件中找到名为name的编译模块
需要注意的是,gn中的part_name一定要跟 json中的component-> name 部件名一致

调用系统部件hilog,封装hilog日志打印

上述目录结构中的selfhilog.h 即为封装hilog日志打印,文件内容如下:

#ifndef OHOS_SELFHILOG_LOG_H
#define OHOS_SELFHILOG_LOG_H
#include <cstring>
#include <string>
#include <unistd.h>
#include "hilog/log.h"
#ifndef SELFHILOG_LOG_TAG
#define SELFHILOG_LOG_TAG "SelfHilog"
#endif
#define FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
#define SELFHILOG_LOG_DOMAIN   0xD00D521  
static constexpr OHOS::HiviewDFX::HiLogLabel SELFHILOG_LOG_LABEL = {LOG_CORE, SELFHILOG_LOG_DOMAIN, SELFHILOG_LOG_TAG};
#define SELFHILOG_HILOG_PRINT(Level, fmt, ...)                                                                 \
    (void)OHOS::HiviewDFX::HiLog::Level(SELFHILOG_LOG_LABEL, "%{public}d [%{public}s:%{public}d] " fmt, gettid(), FILENAME, \
                                        __LINE__, ##__VA_ARGS__)
#define SELFHILOG_LOGE(fmt, ...) SELFHILOG_HILOG_PRINT(Error, fmt, ##__VA_ARGS__)
#define SELFHILOG_LOGI(fmt, ...) SELFHILOG_HILOG_PRINT(Info, fmt, ##__VA_ARGS__)
#define SELFHILOG_LOGD(fmt, ...) SELFHILOG_HILOG_PRINT(Debug, fmt, ##__VA_ARGS__)
#endif // OHOS_SELFHILOG_LOG_H

因为篇幅原因我删除了所有空行,看起来有点紧凑了,关于hilog的原始用法善用百度,这块教程很多,关于封装部分就是SELFHILOG_HILOG_PRINT这个宏函数,如何看懂这个宏函数?
首先看宏函数参数,一共有三 Level, fmt, …

  1. 参数 Level,宏函数中参数是直接替换的,这个Level会被替换为你传入的字面值,如下面SELFHILOG_LOGE的定义,传入的Level为Error,那么函数体其实就是直接调用Hilog::Error函数
  2. 参数 fmt, ... 这俩是表示格式化输入的不定参数,fmt表示格式, … 表示输入的参数 , SELFHILOG_HILOG_PRINT的函数体参数 "%{public}d [%{public}s:%{public}d] " fmt 这是一个参数位置,C++函数中以逗号分隔一个参数, "%{public}d [%{public}s:%{public}d] " fmt 表示的是一个由两部分拼接而成字符串语句, gettid(), FILENAME, __LINE__ 三个值分别填入第一部分 "%{public}d [%{public}s:%{public}d] ",##__VA_ARGS__ 表示…可变参数,按格式填入第二部分fmt
    因为使用了Hilog部件提供的hilog日志接口,那么在哪里依赖hilog的库以及头文件呢?
    deps = []             #部件内部依赖
    external_deps = [   
        "c_utils:utils",
        "hilog:libhilog",
    ]   #部件间依赖
    part_name = "hello"   #所属部件名称,必选

答案是在gn文件的external_deps中,依赖的形式为 部件名:模块名
除此之外还需要在json文件中添加如下内容:

    "deps": {            
    "components": [
        "hilog",
        "c_utils"
    ],
    "third_party": []
    }, 

修改以上两部分即可跨部件使用另外部件中的模块了
根据C++的规则,使用第三方so库有两种方式: vs studio演示动态库的两种调用方式1 vs studio演示动态库的两种调用方式2

  1. so库文件 , so库头文件(显式加载,通过获取函数地址指针来调用so库中的函数)
  2. so库文件,so库头文件,so库函数地址导入库.a文件(隐式加载,通过so函数导入库.a文件得到so库函数地址来调用so库中的函数)
    不管使用哪种方式,我们都需要使用so库头文件,在selfhilog.h文件中确实 #include "hilog/log.h",但是有没有注意到一点,我们并没有在hello项目中手动指出 hilog/log.h的文件位置,那么编译器从哪里找到的头文件位置呢? 这个疑问先按下不表,接着看下面内容
调用self_share部件so库

调用自定义部件库的前提是你得有这个部件库,下面就先创建这个部件库
创建一个最简单的so部件库只需四个文件,跟上面创建exe一样
.h文件

#ifndef _SELFSHARE_H_
#define _SELFSHARE_H_
#ifdef __cplusplus
extern "C" {
#endif
void selfshared_helloword(void);
#ifdef __cplusplus
}
#endif
#endif //_SELFSHARE_H_

.cpp文件

#include "selfshare.h"
#include <stdio.h>
void selfshared_helloword(void)
{
    printf("selfshare say : hello world \n");
}

.gn文件

import("//build/ohos.gni")   #导入编译模板
config("libselfshare_helloworld_config") {
  visibility = [ ":*" ]
  include_dirs = [ "include" ]
}
ohos_shared_library("selfshare_helloworld") {  #可执行模块
    sources = [   #模块源码
        "src/selfshare.cpp"
    ]
    public_configs = [ ":libselfshare_helloworld_config" ]
    #all_dependent_configs 逐层递归传递变量        查看帮助gn all_dependent_configs --help
    cflags = []
    cflags_c = []
    cflags_cc = []
    ldflags = []
    configs = []
    deps = []             #部件内部依赖

    external_deps = [
    ]
    part_name = "self_share"   #所属部件名称,必选
}

.json文件

{
    "name": "@ohos/self_share",		                         
    "description": "share lib",		                   
    "version": "3.1.0",			                              
    "license": "Apache License 2.0",			              
    "publishAs": "code-segment",		                        
    "segment": {						
        "destPath": "sample/self_share"
    },					                                          
    "dirs": {},	                   
    "scripts": {},			                                     
    "component": {			                                     
        "name": "self_share",			                        
        "subsystem": "sample",		                                
        "syscap": [],				                            
        "features": [],                                          
        "adapted_system_type": ["standard"],		                        
        "rom": "",                                           
        "ram": "",                                           
        "deps": {              
        "components": [
        ],
        "third_party": []
      },  
        "build": {				                                
            "sub_component": [
                "//sample/self_share:selfshare_helloworld"
            ],			                                      
            "inner_kits": [
                {
                    "name": "//sample/self_share:selfshare_helloworld",
                    "header": {
                      "header_files": [
                        "selfshare.h"
                      ],
                      "header_base": "//sample/self_share/include"
                    }
                }   
            ],						         
            "test": []							         
        }
    }
 }

.h跟.cpp文件就不说了,这里的关键是.gn跟.json文件

  1. 相比于上文创建一个exe,这里用的是 ohos_shared_library()函数模板创建一个动态库,跟上文的gn文件不同在于,这里使用了两个新函数,config()public_configs()来代替 include_dirs包含头文件目录,public_configs()函数的作用是将当前模块的头文件目录暴露给直接链接当前模块的模块,有点绕,白话就是如果一个exe依赖链接了这个库,那么这个库的头文件目录会自动暴露给这个exe,好了到这里应该能明白为什么上面链接使用hilog库却没有手动包含hilog头文件路径了么,答案就是使用了 public_configs()函数,但是这个函数仅仅能对一个exe的直接依赖链接暴露文件路径,无法对嵌套依赖链接暴露,啥意思呢?
    有一个库叫A.so,A依赖链接了hilog, 现在有个B.exe,B依赖链接了A.so,现在存在两层依赖, A直接依赖hilog,B直接依赖A,如果想在B中使用hilog的原生接口是无法找到hilog的头文件的,因为B不是直接依赖hilog库,public_configs()函数无法嵌套暴露包含的路径,那么有没有办法嵌套暴露呢?答案是使用 all_dependent_configs函数,当然了我这里并不打算演示因为演示的篇幅太长了,再写下去就跟写书一样了,各位学会了这篇的内容可以自行验证
  2. 这里的json文件内容也跟上面创建exe不一样,这里多使用了build->inner_kits,这个字段用于告诉gn,inner_kits里面的内容需要对别的部件暴露,方便别的部件使用部件间依赖使用本部件的模块,name字段写模块的名字(需使用全路径),header_files写需要暴露的头文件,header_base写header_files中头文件的位置
    调用本部件的方法跟上文调用hilog的方法一样,需要在gn文件的external_deps中添加 本部件:模块,在json文件的deps->components添加本部件
调用self_static部件a库

a库(静态链接库)的构建方式跟so库基本一致,唯一不一样的是ohos的创建函数模板,a库使用 ohos_static_library()函数模板
.h

#ifndef _SELFSTATIC_H_
#define _SELFSTATIC_H_
#ifdef __cplusplus
extern "C" {
#endif
void selfstatic_helloword(void);
#ifdef __cplusplus
}
#endif
#endif //_SELFSTATIC_H_

.cpp

#include "selfstatic.h"
#include <stdio.h>
void selfstatic_helloword(void)
{
    printf("selfstatic say : hello world \n");
}

.gn

import("//build/ohos.gni")
config("libselfstatic_helloworld_config") {
  visibility = [ ":*" ]
  include_dirs = [ "include" ]
}
ohos_static_library("selfstatic_helloworld"){
    sources = [
        "src/selfstatic.cpp"
    ]
    public_configs = [ ":libselfstatic_helloworld_config" ]
    deps = []
    part_name = "self_static"
}

.json

{
    "name": "@ohos/self_static",		                         
    "description": "static lib",		                   
    "version": "3.1.0",			                              
    "license": "Apache License 2.0",			              
    "publishAs": "code-segment",		                        
    "segment": {						
        "destPath": "sample/self_static"
    },					                                          
    "dirs": {},	                   
    "scripts": {},			                                     
    "component": {			                                     
        "name": "self_static",			                        
        "subsystem": "sample",		                                
        "syscap": [],				                            
        "features": [],                                          
        "adapted_system_type": ["standard"],		                        
        "rom": "",                                           
        "ram": "",                                           
        "deps": {              
        "components": [
        ],
        "third_party": []
      },  
        "build": {				                                
            "sub_component": [
                "//sample/self_static:selfstatic_helloworld"
            ],			                                      
            "inner_kits": [
                {
                    "name": "//sample/self_static:selfstatic_helloworld",
                    "header": {
                      "header_files": [
                        "selfstatic.h"
                      ],
                      "header_base": "//sample/self_static/include"
                    }
                }   
            ],								         
            "test": []							         
        }
    }
 }

调用本部件的方法跟上文调用so库的方法一样,需要在gn文件的external_deps中添加 本部件:模块,在json文件的deps->components添加本部件

编译部件

上面的内容创建了三个部件,在链接了自定义的so库跟a库后,exe的gn文件如下:

import("//build/ohos.gni")   #导入编译模板
ohos_executable("helloworld") {  #可执行模块
    sources = [   #模块源码
        "src/helloworld.cpp"
    ]
    include_dirs = [ #模块依赖头文件目录
        "include"
    ]
    cflags = []
    cflags_c = []
    cflags_cc = []
    ldflags = []
    configs = []
    deps = [ 
   
    ]             #部件内部依赖
    external_deps = [   
        "c_utils:utils",
        "hilog:libhilog",
        "self_share:selfshare_helloworld",
        "self_static:selfstatic_helloworld"
    ]
    part_name = "hello"   #所属部件名称,必选
    install_enable = true #是否默认安装(缺省默认不安装),可选
}

exe的json文件如下:

{
    "name": "@ohos/hello",		                         
    "description": "Hello world example",		                   
    "version": "3.1.0",			                              
    "license": "Apache License 2.0",			              
    "publishAs": "code-segment",		                        
    "segment": {						
        "destPath": "sample/hello"
    },					                                          
    "dirs": {},	                   
    "scripts": {},			                                     
    "component": {			                                     
        "name": "hello",			                        
        "subsystem": "sample",		                                
        "syscap": [],				                            
        "features": [],                                          
        "adapted_system_type": ["standard"],		                        
        "rom": "",                                           
        "ram": "",                                           
        "deps": {              
        "components": [
            "hilog",
            "c_utils",
            "self_share",
            "self_static"
        ],
        "third_party": []
      },  
        "build": {				                                
            "sub_component": [
                "//sample/hello:helloworld" 
            ],			                                      
            "inner_kits": [],						         
            "test": []							         
        }
    }
 }

不知道聪明的你有没有写对呢
在上面构建流程章节已经讲过想自定义一个部件参与编译至少需要三步,下面将本次创建的三个部件添加编译

  1. 在//build/subsystem_config.json中添加如下内容:
  "sample": {
    "path": "sample",
    "name": "sample"
  }

参照subsystem_config.json中其他子系统的添加方式,注意书写格式
该内容表示添加一个子系统sample, 路径就是根目录sample目录,子系统的名字就是sample
2. /vendor/厂家/产品名/config.json中添加如下内容:

{
    "subsystem": "sample",
    "components": [
    {
        "component": "hello",
        "features": []
    },
    {
        "component": "self_share",
        "features": []
    },
    {
        "component": "self_static",
        "features": []
    }  
    ]
}

参照config.json中其他模块的添加方式,注意书写格式
该内容表示将子系统sample下的hello,self_share,self_static三个部件加入到产品构建当中
3. 编译部件
新增的部件有两种构建思路:

  • 单部件构建 : ./build.sh --product-name 产品名 -T helloworld --ccache --no-prebuilt-sdk
  • 全量构建 : ./build.sh --product-name 产品名 --ccache --no-prebuilt-sdk

单部件构建:直接构建helloworld模块,还记得上面说的,模块是最小编译target,可以直接进行指定编译,编译helloworld模块会把依赖项hilog,selfshare_helloworld,selfstatic_helloworld全部编译;在//out目录下查找helloworld跟libselfshare_helloworld.so

find ./ -name "helloworld"
find ./ -name "*selfshare_helloworld*"

将这两个文件上传到板子

hdc file send XXXXXXXX/helloworld  /bin/
hdc file send XXXXXXXX/libselfshare_helloworld.so  /lib64/

因为a库被编译到helloworld中了,所以只要拷贝俩文件就行
在板子上赋予helloworld执行权限,执行helloworld
全量构建:将整个源码编译,做成镜像烧录到开发板,通过hdc链接开发板可以直接运行helloworld,因为我们在gn文件中标记了install_enable = true默认安装
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/870529.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【k8s从节点报错】error: You must be logged in to the server (Unauthorized)

k8s主节点可以获取nodes节点信息&#xff0c;但是从节点无法获取&#xff0c;且报错“error: You must be logged in to the server (Unauthorized)” 排查思路&#xff1a; 当时证书过期了&#xff0c;只处理的主节点的证书过期&#xff0c;没有处理从节点的 kubeadm alpha …

解锁 Starknet 的深层洞察:利用 Dune 构建动态数据可视化

原文&#xff1a;https://dev.to/lordghostx/queries-to-insights-visualizing-starknet-data-with-dune-j8p 作者&#xff1a;LordGhostX 编译&#xff1a;TinTinLand Starknet 的链上数据为其区块链生态系统提供了丰富的洞察。它为用户活动、交易模式和网络交互提供了全面…

【系统架构设计】系统规划

【系统架构设计】系统规划 项目的提出和选择可行性研究与效益分析方案的制订和改进新旧系统的分析和比较 项目的提出和选择 Noriaki Kano 提出了顾客质量模型图 假想质量 &#xff1a; 是客户想当然认为产品应该具备的功能或性能&#xff0c;客户并不能正确描述自己想当然要得…

8.MySQL知识巩固-牛客网练习题

目录 SQL228 批量插入数据 描述 SQL202 找出所有员工当前薪水salary情况 描述 示例1 SQL195 查找最晚入职员工的所有信息描述 示例1 SQL196 查找入职员工时间排名倒数第三的员工所有信息描述 SQL201查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t 描述 SQL…

记一次数据库慢查询的处理方法

1.案发现场 今天打开系统&#xff0c;发现有个页面一直报接口超时&#xff0c;然后定位到该接口和对应的查询sql&#xff0c;拿到navicat中去执行发现执行效率确实很慢&#xff0c;sql和执行时间如下&#xff1a;SELECT DISTINCTr.id,r.province,r.city,r.district,r.NAME,r.lo…

【C++指南】深入剖析:C++中的引用

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C指南》 期待您的关注 目录 引言&#xff1a; 一、引用的基本概念 1. 定义与特性 2. 语法与声明 二、引用的进阶用法 1. 函…

[HNCTF 2022 WEEK2]getflag-入土为安的二十一天

难点读程序&#xff0c;写exp *(unsigned __int8 *)(i a1) >> 4: 这将字节 i a1 右移 4 位&#xff0c;提取出字节的高 4 位。 *(_BYTE *)(i a1): 这获取原字节的低 4 位&#xff08;即&#xff0c;i a1 位置的字节的低 4 位&#xff09;。 (16 * *(_BYTE *)(i a1))…

怎么在网络攻击中屹立不倒

在当今蓬勃发展的网络游戏产业中&#xff0c;服务器安全无疑是企业生存与发展的基石。面对互联网环境中无处不在的DDoS&#xff08;分布式拒绝服务&#xff09;与CC&#xff08;挑战碰撞&#xff09;攻击威胁&#xff0c;游戏服务器的防御能力与高效处理能力显得尤为重要。相较…

EmguCV学习笔记 VB.Net 2.S 特别示例

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 教程VB.net版本请访问&#xff1a;EmguCV学习笔记 VB.Net 目录-CSDN博客 教程C#版本请访问&#xff1a;EmguCV学习笔记 C# 目录-CSD…

ffmpeg的基础命令

文章目录 ffmpeg/ffplay/ffprobe区别ffmpeg 的作用ffplay的作用ffprobe的作用 ffmpeg使用概述功能概述转码过程简单使用FFMPEG -i常用的 -i例子 ff***工具之间共享的选项ffmpeg主要选项ffmpeg提取音视频数据ffmpeg命令修改原有的视频格式ffmpeg命令裁剪和合并视频拼接视频的方式…

计算机网络基础详解:从网络概述到安全保障的全面指南

目录 网络基础详细概述 1. 网络概述 1.1数据通信 1.2资源共享 1.3分布式处理 1.4负载均衡 2. 网络分类 2.1按覆盖范围&#xff1a; 2.1.1局域网 (LAN)&#xff1a; 2.1.2城域网 (MAN)&#xff1a; 2.1.3广域网 (WAN)&#xff1a; 2.2按拓扑结构&#xff1a; 2.2.1…

python request 发送包含文件请求

file_path rD:\work\200K.pdf # 额外的参数 # 请求文件 url "http://192.168.1.111:8888/test"payload {param1: test,param2: test2} files [(file, (file_path, open(file_path, rb), application/pdf)) ] headers {} response requests.request("POST&…

X-Recon:一款针对Web安全的XSS安全扫描检测工具

关于X-Recon X-Recon是一款功能强大的Web安全扫描与检测工具&#xff0c;该工具能够帮助广大研究人员识别网页端输入数据&#xff0c;并执行XSS扫描任务。 功能介绍 1、子域名发现&#xff1a;检索目标网站的相关子域名并将其整合到白名单中。这些子域名可在抓取过程中使用&am…

yolov8旋转框+关键点检测

一、Yolov8obb_kpt -----------------------------------现已在v8官方库上更新旋转框分割算法和旋转框关键点检测算法-------------------------- ------------------------------------------- https://github.com/yzqxy/ultralytics-obb_segment---------------------------…

苗情灾情监控系统的工作原理

TH-MQ1苗情灾情监控系统&#xff0c;也常被称为作物生长检测仪&#xff0c;是现代农业技术中的一项重要创新&#xff0c;它集成了物联网、大数据、人工智能等先进技术&#xff0c;为农业生产提供了全面、精准的监测与诊断服务。通过集成高清摄像头、高精度传感器、无人机等多种…

【TCP/IP】自定义应用层协议,常见端口号

互联网中&#xff0c;主流的是 TCP/IP 五层协议 5G/4G 上网&#xff0c;是有自己的协议栈&#xff0c;要比 TCP/IP 更复杂&#xff08;能够把 TCP/IP 的一部分内容给包含进去了&#xff09; 应用层 可以代表我们所编写的应用程序&#xff0c;只要应用程序里面用到了网络通信…

VueX 使用

1.简介 就是用来多组件共享数据的实现用的 2.使用VueX 因为使用的是vue2 所以下的是vuex3 若是vue3 必须下的是 vue4 npm i vuex3 3.搭建环境 1.创建 src/store/index.js //该文件用于创建一个Vuex中最为核心的store//引入VueX import Vuex from vuex import Vue from vu…

微服务系列:Spring Cloud 之 Feign、Ribbon、Hystrix 三者超时时间配置

Feign 自身有超时时间配置 Feign 默认集成的 Ribbon 中也有超时时间配置 假如我们又使用了 Hystrix 来实现熔断降级&#xff0c;Hystrix 自身也有一个超时时间配置 注: spring-cloud-starter-openfeign 低一点的版本中默认集成的有 Hystrix&#xff0c;高版本中又移除了。 …

XSS-DOM

文章目录 源码SVG标签Dom-Clobbringtostring 源码 <script>const data decodeURIComponent(location.hash.substr(1));;const root document.createElement(div);root.innerHTML data;// 这里模拟了XSS过滤的过程&#xff0c;方法是移除所有属性&#xff0c;sanitize…

如何发布自己的NPM包详细步骤

前言 在前端开发中&#xff0c;将自己编写的 Vue 组件或插件打包并发布到 NPM 上&#xff0c;不仅可以方便自己在其他项目中复用&#xff0c;还能分享给更多的开发者使用。本文将从 NPM 注册、登录与发布流程&#xff0c;及如何通过 Vue CLI 打包插件的角度详细介绍如何发布 V…