eBPF BCC开源工具简介
目录
官方链接
编译安装
ubuntu版本
安装
examples
tools
hello_world.py demo
运行报错
网上目前的解决办法
错误分析过程
python版本检测
libbcc库检查
python3 bcc库检查
正常输出
监控进程切换
运行输出
监控CPU直方图
缓存命中率监控:cachestat
cachetop
BCC开发指南
官方链接
主页:https://github.com/iovisor/bcc
bcc开发:https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md
编译安装
ubuntu版本
wj@wj:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.2 LTS
Release: 22.04
Codename: jammy
安装
git clone https://github.com/iovisor/bcc.git
mkdir bcc/build; cd bcc/build
cmake ..
make
sudo make install
cmake -DPYTHON_CMD=python3 .. # build python3 binding
pushd src/python/
make
sudo make install
popd安装路径:
/usr/share/bcc/tools
可以看到 /usr/share/bcc 目录下,有4个文件夹,examples introspection man tools 。
在examples 文件下,有一些简单的demo。tools文件下有 bcc的各种工具。
examples
tools
hello_world.py demo
#!/usr/bin/python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")# run in project examples directory with:
# sudo ./hello_world.py"
# see trace_fields.py for a longer examplefrom bcc import BPF# This may not work for 4.17 on x64, you need replace kprobe__sys_clone with kprobe____x64_sys_clone
BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print()
上述 hello_world.py程序中会监测 kprobe__sys_clone 事件,一旦内核监测到 kprobe__sys_clone 事件产生,就会打印 Hello, World! 出来。
运行报错
wj@wj:/usr/share/bcc/examples$ sudo python3 hello_world.py
Traceback (most recent call last):File "/usr/share/bcc/examples/hello_world.py", line 9, in <module>from bcc import BPFFile "/usr/lib/python3/dist-packages/bcc/__init__.py", line 27, in <module>from .libbcc import lib, bcc_symbol, bcc_symbol_option, bcc_stacktrace_build_id, _SYM_CB_TYPEFile "/usr/lib/python3/dist-packages/bcc/libbcc.py", line 20, in <module>lib.bpf_module_create_b.restype = ct.c_void_pFile "/usr/lib/python3.10/ctypes/__init__.py", line 387, in __getattr__func = self.__getitem__(name)File "/usr/lib/python3.10/ctypes/__init__.py", line 392, in __getitem__func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/x86_64-linux-gnu/libbcc.so.0: undefined symbol: bpf_module_create_b
网上目前的解决办法
主要还是python版本问题,将python2切换为python3。而我这边显然不是这个问题,因为我的机子上只有python3
错误分析过程
根据报错信息,和报错相关的路径:
/lib/x86_64-linux-gnu/libbcc.so.0 :bcc库采用的libbcc.so.0
/usr/lib/python3/dist-packages/bcc :报错的bcc库
python版本检测
使用的均为python3,没有python2,所以不存在版本问题。
libbcc库检查
wj@wj:/usr/share/bcc/examples$ ls -lh /lib/x86_64-linux-gnu/ |grep libbcc
-rw-r--r-- 1 root root 5.0M 11月 5 14:48 libbcc.a
-rw-r--r-- 1 root root 1.5M 11月 5 14:46 libbcc_bpf.a
lrwxrwxrwx 1 root root 15 1月 19 2021 libbcc_bpf.so -> libbcc_bpf.so.0
lrwxrwxrwx 1 root root 20 11月 5 14:54 libbcc_bpf.so.0 -> libbcc_bpf.so.0.28.0
-rw-r--r-- 1 root root 51K 1月 19 2021 libbcc_bpf.so.0.18.0
-rw-r--r-- 1 root root 2.8M 11月 5 14:48 libbcc_bpf.so.0.28.0
-rw-r--r-- 1 root root 243K 11月 5 14:47 libbcc-loader-static.a
lrwxrwxrwx 1 root root 11 1月 19 2021 libbcc.so -> libbcc.so.0
lrwxrwxrwx 1 root root 16 11月 5 14:54 libbcc.so.0 -> libbcc.so.0.28.0
-rw-r--r-- 1 root root 3.3M 1月 19 2021 libbcc.so.0.18.0
-rw-r--r-- 1 root root 105M 11月 5 14:47 libbcc.so.0.28.0
可以看到libbcc库的实际指向为: libbcc.so.0 -> libbcc.so.0.28.0
根据报错内容,python库需要bpf_module_create_b,而libbcc.so.0.28.0中没有
可以通过以下命令查看:
wj@wj:/usr/share/bcc/examples$ strings /lib/x86_64-linux-gnu/libbcc.so.0.28.0 |grep bpf_module_create_
bpf_module_create_c
bpf_module_create_c_from_string
bpf_module_create_c.cold
bpf_module_create_c_from_string.cold
bpf_module_create_c
bpf_module_create_c_from_string
此时注意到上一个步骤中的libbcc.so.0.18.0,同样进行bpf_module_create_b检查
wj@wj:/usr/share/bcc/examples$ strings /lib/x86_64-linux-gnu/libbcc.so.0.18.0 |grep bpf_module_create_
bpf_module_create_b
bpf_module_create_c
bpf_module_create_c_from_string
发现存在bpf_module_create_b,即便不进行时间对比,通过版本号0.18.0与0.28.0也知道,
python3的bcc库竟然请求的是老版(0.18.0)的bcc lib库
python3 bcc库检查
wj@wj:/usr/share/bcc/examples$ ll /usr/lib/python3/dist-packages/bcc/
总计 212
drwxr-xr-x 3 root root 4096 10月 4 15:36 ./
drwxr-xr-x 155 root root 12288 11月 5 14:56 ../
-rw-r--r-- 1 root root 2566 1月 19 2021 containers.py
-rw-r--r-- 1 root root 20914 1月 19 2021 disassembler.py
-rw-r--r-- 1 root root 58581 1月 19 2021 __init__.py
-rw-r--r-- 1 root root 12951 1月 19 2021 libbcc.py
-rw-r--r-- 1 root root 4693 1月 19 2021 perf.py
drwxr-xr-x 2 root root 4096 10月 4 15:36 __pycache__/
-rw-r--r-- 1 root root 9656 1月 19 2021 syscall.py
-rw-r--r-- 1 root root 40588 1月 19 2021 table.py
-rw-r--r-- 1 root root 1604 1月 19 2021 tcp.py
-rw-r--r-- 1 root root 9102 1月 19 2021 usdt.py
-rw-r--r-- 1 root root 4904 1月 19 2021 utils.py
-rw-r--r-- 1 root root 23 1月 19 2021 version.py
根据文件时间可以确定,确实都是21年的老库,遂进行替换,先查找bcc源码中的bcc python库:
wj@wj:/usr/share/bcc/examples$ find / -name libbcc.py -ls 2>/dev/null408370 16 -rw-rw-r-- 1 wj wj 14561 11月 5 14:44 /home/wj/bcc/build/src/python/bcc-python3/bcc/libbcc.py408643 16 -rw-r--r-- 1 root root 14561 11月 5 14:44 /home/wj/bcc/build/src/python/bcc-python3/build/lib/bcc/libbcc.py407310 16 -rw-rw-r-- 1 wj wj 14561 11月 5 14:43 /home/wj/bcc/src/python/bcc/libbcc.py4496431 16 -rw-r--r-- 1 root root 12951 1月 19 2021 /usr/lib/python3/dist-packages/bcc/libbcc.py
wj@wj:/usr/share/bcc/examples$ cp -r /home/wj/bcc/build/src/python/bcc-python3/bcc/* /usr/lib/python3/dist-packages/bcc/
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/containers.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/disassembler.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/__init__.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/libbcc.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/perf.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/syscall.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/table.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/tcp.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/usdt.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/utils.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/version.py': 权限不够
sudo cp -r /home/wj/bcc/build/src/python/bcc-python3/bcc/* /usr/lib/python3/dist-packages/bcc/
参考:AttributeError: /lib/x86_64-linux-gnu/libbcc.so.0: undefined symbol: bpf_module_create_b-CSDN博客
正常输出
可以看到 内核捕获到了 kprobe__sys_clone 事件,并打印出 Hello, World! 出来。
监控进程切换
//task_switch.py
#!/usr/bin/python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")from bcc import BPF
from time import sleepb = BPF(src_file="task_switch.c")
b.attach_kprobe(event_re="^finish_task_switch$|^finish_task_switch\.isra\.\d$",fn_name="count_sched")# generate many schedule events
for i in range(0, 100): sleep(0.01)for k, v in b["stats"].items():print("task_switch[%5d->%5d]=%u" % (k.prev_pid, k.curr_pid, v.value))
k.prev_pid :表示上一个进程的 pid
k.curr_pid :表示切换到当前进程 pid
task_switch.c
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>struct key_t {u32 prev_pid;u32 curr_pid;
};BPF_HASH(stats, struct key_t, u64, 1024);
int count_sched(struct pt_regs *ctx, struct task_struct *prev) {struct key_t key = {};u64 zero = 0, *val;key.curr_pid = bpf_get_current_pid_tgid();key.prev_pid = prev->pid;// could also use `stats.increment(key);`val = stats.lookup_or_try_init(&key, &zero);if (val) {(*val)++;}return 0;
}
运行输出
wj@wj:/usr/share/bcc/examples/tracing$ sudo python3 task_switch.py
[sudo] wj 的密码:
task_switch[ 879-> 0]=1
task_switch[ 0->14938]=2
task_switch[14959-> 0]=1
task_switch[ 0->14964]=2
task_switch[ 0-> 71]=2
task_switch[ 0->15021]=1
task_switch[14969->14939]=1
task_switch[11713-> 0]=1
task_switch[ 52-> 0]=1
task_switch[ 0-> 809]=4
task_switch[ 2402-> 0]=6
task_switch[ 928-> 0]=1
task_switch[ 5247-> 0]=3
task_switch[ 0-> 437]=3
task_switch[ 0-> 7458]=6
task_switch[ 0->14986]=1
task_switch[11411-> 0]=3
task_switch[ 2674-> 0]=5
task_switch[15064-> 0]=1
task_switch[ 8767-> 0]=48
task_switch[14939->14969]=1
task_switch[14998-> 0]=1
task_switch[ 0->14921]=2
task_switch[14986->14959]=2
task_switch[ 0->15194]=1
task_switch[ 0-> 16]=1
task_switch[ 0-> 15]=14
task_switch[ 901->15194]=1
task_switch[ 22-> 0]=1
task_switch[ 1816-> 0]=7
task_switch[ 0-> 40]=1
task_switch[14959->14986]=1
task_switch[ 0-> 901]=1
task_switch[14577-> 0]=1
task_switch[ 0-> 5247]=3
task_switch[ 58-> 0]=1
task_switch[14938-> 0]=2
task_switch[ 0->11411]=3
task_switch[ 34-> 0]=1
task_switch[15194-> 0]=2
task_switch[ 0-> 58]=1
task_switch[ 0-> 28]=1
task_switch[ 7458-> 0]=7
task_switch[ 0->15010]=3
task_switch[ 926-> 0]=1
task_switch[14921-> 0]=2
task_switch[ 46-> 0]=1
task_switch[14964-> 0]=3
task_switch[15030-> 0]=3
task_switch[ 15-> 0]=14
task_switch[ 40-> 0]=1
task_switch[ 0->14374]=5
task_switch[ 0->15064]=1
task_switch[15129-> 0]=1
task_switch[ 0-> 8767]=47
task_switch[ 0->15129]=1
task_switch[ 809-> 0]=3
task_switch[14374-> 0]=5
task_switch[ 0-> 2674]=5
task_switch[ 0-> 34]=1
task_switch[ 0-> 926]=1
task_switch[ 0->15211]=100
task_switch[14969-> 0]=1
task_switch[ 0->14969]=1
task_switch[ 0->11713]=1
task_switch[ 437-> 0]=3
task_switch[ 835-> 0]=11
task_switch[ 2035-> 0]=11
task_switch[ 8767-> 29]=10
task_switch[ 0->14577]=1
task_switch[ 0-> 1816]=7
task_switch[ 0->14998]=1
task_switch[ 0-> 928]=1
task_switch[15010-> 0]=3
task_switch[ 0-> 2402]=6
task_switch[ 0->14981]=1
task_switch[ 0-> 2142]=1
task_switch[ 953-> 0]=1
task_switch[ 29-> 8767]=10
task_switch[ 835-> 8767]=1
task_switch[ 0-> 835]=12
task_switch[ 28-> 0]=1
task_switch[ 0-> 953]=1
task_switch[ 0-> 2035]=11
task_switch[14981->14964]=1
task_switch[ 809-> 7458]=1
task_switch[ 1702-> 0]=1
task_switch[ 0-> 52]=1
task_switch[ 16-> 0]=1
task_switch[ 0-> 879]=1
task_switch[ 0->15030]=3
task_switch[15211-> 0]=100
task_switch[ 0-> 22]=1
task_switch[ 71-> 0]=2
task_switch[15021-> 0]=1
task_switch[ 0-> 46]=1
task_switch[ 2142-> 0]=1
监控CPU直方图
tools/cpudist: Summarize on- and off-CPU time per task as a histogram.
tools/cpudist:将每个任务的 CPU 开启和关闭时间总结为直方图。
wj@wj:/usr/share/bcc/tools$ sudo python3 ./cpudist
Tracing on-CPU time... Hit Ctrl-C to end.
^Cusecs : count distribution0 -> 1 : 5 |* |2 -> 3 : 38 |******** |4 -> 7 : 106 |*********************** |8 -> 15 : 134 |****************************** |16 -> 31 : 156 |*********************************** |32 -> 63 : 177 |****************************************|64 -> 127 : 142 |******************************** |128 -> 255 : 63 |************** |256 -> 511 : 79 |***************** |512 -> 1023 : 21 |**** |1024 -> 2047 : 7 |* |2048 -> 4095 : 1 | |4096 -> 8191 : 1 | |
wj@wj:/usr/share/bcc/tools$
缓存命中率监控:cachestat
- tools/cachestat: Trace page cache hit/miss ratio. Examples.
sudo python3 ./cachestat
cachetop
sudo python3 ./cachetop
以上都是自定义在 examples 和 tools 中的工具。如果需要自己开发 bcc 程序,那应该怎么样使用呢?可以参考如下链接。
BCC开发指南
https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md
相关文章:

eBPF BCC开源工具简介
目录 官方链接 编译安装 ubuntu版本 安装 examples tools hello_world.py demo 运行报错 网上目前的解决办法 错误分析过程 python版本检测 libbcc库检查 python3 bcc库检查 正常输出 监控进程切换 运行输出 监控CPU直方图 缓存命中率监控:caches…...
Linux上后台运行进程(nohub、screen和tmux )
文章目录 Linux上后台运行进程(nohub、screen和tmux )nohupscreen虚拟终端安装screen使用 tmux终端复用器[个人推荐]安装tmux使用 Linux上后台运行进程(nohub、screen和tmux ) 命令行的典型使用方式是,打开一个终端窗…...

javaee实验:搭建maven+spring boot开发环境,开发“Hello,Spring Boot”应用
目录 mavenspringboot实验目的实验内容环境的搭建 在开发中,maven和spring都是非常常用、非常重要的管理工具和框架,今天就在这里使用idea进行环境的搭建和创建第一个spring程序 maven 1.1maven是一个跨平台的项目管理工具(主要管理jar包&am…...

重新思考边缘负载均衡
本文介绍了Netflix在基于轮询的负载均衡的基础上,集成了包括服务器使用率在内的多因素指标,并对冷启动服务器进行了特殊处理,从而优化了负载均衡逻辑,提升了整体业务性能。原文: Rethinking Netflix’s Edge Load Balancing[1] 我…...
构建一个CAN报文周期任务类
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、can周期任务类构建总结 前言 提示:这里可以添加本文要记录的大概内容: 最近想着有时间实现总线报文收发的动态的配置,…...

深入理解计算机系统CS213 - Lecture 02
Bits, Bytes, and Integer 1.位运算与条件运算 &,|,^,~ 是做位运算。诸位01运算。 &&,||,!是判断条件真假,而后返回0或1。 2. 位移 x << y:左移y位ÿ…...

【KVM】KVM介绍及功能概述
前言 大家好,我是秋意零。 今天介绍的内容是KVM的概述,以及它所支持的基本功能。 👿 简介 🏠 个人主页: 秋意零🔥 账号:全平台同名, 秋意零 账号创作者、 云社区 创建者…...

centos7安装MySQL
引言 在安装与卸载的时候,用户全部要切换为root 在使用MySQL的时候,尽量使用root权限,便于使用(root权限不会开的可以去百度找一下自己服务器类型的开启方式)在本文章我将使用xshell7进行操作,你也可以使用…...
leetcode做题笔记215. 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,6,4], k 2…...

Linux Vim撤销和恢复撤销快捷键
使用 Vim 编辑文件内容时,经常会有如下 2 种需求: 对文件内容做了修改之后,却发现整个修改过程是错误或者没有必要的,想将文件恢复到修改之前的样子。 将文件内容恢复之后,经过仔细考虑,又感觉还是刚才修改…...
【BUG】记一次Maven install 报错 Could not find artifact ...:pom:0.0.1-SNAPSHOT
问题描述 创建一个maven多模块项目,执行install报错Could not find artifact …:pom:0.0.1-SNAPSHOT,然后点击clean也是报错。 原因分析: 从错误日志发现提示无法从远程maven仓库下载父模块,一看应该是哪里配置了强制从远程仓库…...

逆向学习记录(4)adb
adb用于PC和手机端通讯。 常用命令如下: 如果不是模拟器(模拟器一般都有自己的adb),adb会出现在Andirod的SDK中,路径为:Android/SDK/platform-tools。 最好加入环境变量中。...

Windows Server 2016使用MBR2GPT.EXE教程!
什么是MBR2GPT.exe? MBR2GPT.exe是微软提供的专业工具,可在命令提示符下运行。使用该工具可以将引导磁盘从MBR转换为GPT分区样式,而无需修改或删除所选磁盘上的任何内容。 在Windows Server 2019和Windows 10(1703…...

SpringBoot项目多环境开发
1.yml文件(旧) 说明:旧的写法。 #应用环境 spring:profiles:active: dev --- #设置环境#生产环境 spring:profiles: pro server:port: 81--- #开发环境 spirng:profiles: dev server:port: 81--- #测试环境 spring:profiles: test server:p…...
godot4实现一个单例类,作为公共数据共享类
在 Godot 4 中,你可以通过创建一个自动加载的脚本来实现单例类,用于作为公共的数据总线。你需要做的是: 1. 创建一个新的 GDScript 文件,例如 GlobalData.gd,并在其中定义你想要共享的变量和函数。 2. 然后࿰…...
AcWing - 5287. 数量 - 组合数求解+思维
最多只有k个位置满足,ai ! i 所以从0-k进行遍历,对于kj: 0时,所有位置上的数字都等于i,只有一种 1时,没有 2时,排列只有两种,1 2 或者 2 1,只有一种情况满足 同理3和4可以…...

《实战:如何搭建一个完整的 Vue2.0 项目》- 7、Vue2.x 项目 webpack 4 升级 5(半自动升级)
1.自动升级 先全局安装升级插件 npm i npm-check npm-check-updates -g检查依赖 npm-check更新检查后的依赖并展示版本号,此时 package.json还没有更新 npm-check-updates升级 package.json,下图显示更新版本,此时 package.json文件已变更…...
Python教程---Python基础语法2
1.变量和字面量(常量) 字面量就是一个一个的值,比如:1,2,3,4,5,6,‘HELLO’ 字面量所表示的意思就是它的字面的值,在程序中可以直接使用字面量 变量(variable)变量可以用来保存字面量,并且变量中保存的字面量是不定的变量本身没有任何意思,它会根据不同的字面量…...
Conda创建软件安装环境
Conda 安装软件并创建环境 Python创建虚拟环境 conda create -n env_name python3.11 进入创建的虚拟环境 conda activate env_name 安装软件 conda install -c bioconda software_name...
MySQL | MySQL 为什么不推荐使用JOIN
MySQL 为什么不推荐使用JOIN MySQL 不推荐使用 JOIN 的说法是过于简化的。实际上,在某些情况下使用 JOIN 是非常有用的,但在其他情况下可能会带来性能问题、复杂性和可维护性问题以及重复数据等问题。 首先我们需要知道JOIN语句是用于将多个表中的数据…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...