TSMaster二次开发实战:如何用Python搞定CAN/CANFD事件回调(附完整代码)
TSMaster二次开发实战如何用Python搞定CAN/CANFD事件回调附完整代码在汽车电子和嵌入式开发领域TSMaster作为一款强大的总线分析、仿真与测试工具其二次开发能力为工程师提供了极大的灵活性。当我们需要深度集成自动化测试流程、定制化数据监控或实现复杂的交互逻辑时仅仅依靠图形界面往往捉襟见肘。这时Python凭借其简洁的语法和丰富的生态成为连接TSMaster核心功能与我们自定义业务逻辑的理想桥梁。而事件回调机制正是这座桥梁上最关键的枢纽之一。想象一下这样的场景你正在开发一个ECU自动化测试台架需要实时捕获特定CAN报文并根据其内容动态调整后续的仿真信号或者你希望在不干扰总线正常通信的前提下对即将发出的报文进行最后一刻的修改。这些需求都指向了TSMaster二次开发中的“事件驱动”编程模型。本文将从一个实战开发者的视角带你深入理解如何用Python驾驭TS/CANFD的事件回调避开那些新手常踩的“坑”并分享提升代码健壮性和性能的独家技巧。无论你是刚接触TSMaster API的工程师还是希望优化现有脚本的开发者这里都有你需要的干货。1. 理解TSMaster事件回调的核心理念在开始敲代码之前我们必须先厘清事件回调在TSMaster二次开发中的角色。它本质上是一种异步通知机制。不同于你主动去“轮询”或“读取”总线状态回调是TSMaster库在特定事件如报文收发发生时主动调用你预先注册好的一个函数。这种模式将程序的主动权交给了事件流使得你的代码能够即时响应总线上的变化非常适合处理实时性要求高的任务。TSMaster主要提供了两类与CAN/CANFD相关的事件回调后处理事件回调在报文已经被发送到总线或从总线接收之后触发。通常用于数据记录、监控、分析和触发后续的非实时逻辑。预发送事件回调在报文即将被发送到总线之前触发。这是实现报文内容动态修改、发送过滤或条件触发的唯一入口功能非常强大。理解这两者的区别至关重要。预发送回调发生在发送流程的末端给你最后一次修改报文数据的机会但它对代码的执行效率有严格要求任何耗时的操作都可能导致发送时序错乱。而后处理回调则宽松得多你可以在这里进行相对复杂的处理比如写入数据库或进行数据聚合。注意预发送回调函数中应避免进行文件I/O、网络请求或任何可能引起阻塞的操作确保其执行时间极短通常应在微秒级内完成。为了更清晰地对比我们来看一下这两类回调的关键差异特性维度预发送事件回调 (Pre-TX Event)后处理事件回调 (Post-TX/RX Event)触发时机报文被应用程序提交即将放入硬件发送队列之前报文已成功发送到总线或已从总线接收之后主要用途动态修改报文数据、DLC、ID实现条件发送过滤特定报文数据记录、监控、分析、触发后续测试步骤、统计性能要求极高必须快速返回否则影响发送时序相对宽松但仍需注意避免阻塞主线程能否阻止发送可以通过不将报文加入发送队列不能事件已发生数据访问可以修改报文对象的所有字段只能读取报文对象的字段副本2. 搭建你的第一个事件回调项目从零到一理论说得再多不如动手实践。让我们从一个最小化的、可运行的示例开始一步步构建一个具备完整事件回调功能的Python项目。这个示例将演示如何接收CAN报文并在发送前修改特定ID的报文数据。首先确保你的开发环境已就绪。你需要安装Python推荐3.7及以上版本以及TSMaster软件。TSMaster的Python API通常以TSMasterAPI.pyd或类似名称的动态链接库形式提供需要将其放置在Python解释器能够找到的路径下或者与你的脚本放在同一目录。2.1 项目结构与初始化创建一个新的项目目录例如tsmaster_callback_demo。在里面我们创建两个主要文件requirements.txt: 用于管理项目依赖目前主要是TSMaster库文件需手动放置。callback_demo.py: 我们的主脚本。项目初始化不仅仅是导入库。一个健壮的脚本应该包含完善的错误处理和资源管理。下面是一个增强版的初始化代码块它比简单的import和initialize做了更多事情#!/usr/bin/env python3 # -*- coding: utf-8 -*- TSMaster CAN/CANFD 事件回调实战演示 作者你的名字 描述演示如何注册和处理预发送、后处理事件回调包含错误处理和资源清理。 import sys import time import ctypes from ctypes import c_int32, byref # 尝试导入TSMaster API并处理可能的导入错误 try: # 根据你的TSMaster安装路径可能需要调整导入方式 # 例如sys.path.append(rC:\TSMaster\API) from TSMasterAPI import * from TSEnum import * from TSStruct import * from TSCallback import * print([INFO] TSMaster API 模块导入成功。) except ImportError as e: print(f[ERROR] 无法导入TSMaster模块: {e}) print(请确保TSMaster的Python库文件如TSMasterAPI.pyd在Python路径中。) sys.exit(1) def safe_initialize(app_nameMyCallbackApp): 安全地初始化TSMaster库。 参数: app_name: 应用程序标识名称。 返回: bool: 初始化成功为True失败为False。 # 初始化库是所有操作的前提 ret initialize_lib_tsmaster(app_name.encode(utf-8)) if ret ! 0: print(f[ERROR] 初始化TSMaster库失败错误码: {ret}) return False print(f[INFO] TSMaster库初始化成功 (App: {app_name})) return True def configure_can_channel(channel_indexCHANNEL_INDEX.CHN1, can_count1, lin_count0): 配置CAN/LIN通道数量。 if tsapp_set_can_channel_count(can_count) ! 0: print([ERROR] 设置CAN通道数失败。) return False if tsapp_set_lin_channel_count(lin_count) ! 0: print([ERROR] 设置LIN通道数失败。) return False print(f[INFO] 通道配置完成: CAN{can_count}, LIN{lin_count}) return True这个初始化段做了几件关键事使用try...except优雅地处理模块导入失败将初始化操作封装成函数便于错误判断和流程控制添加了详细的日志输出便于调试。2.2 定义回调函数事件处理的核心回调函数是你处理总线事件的“大脑”。其函数签名是固定的由TSMaster API定义。下面我们定义两个典型的回调函数一个用于处理接收到的CAN报文后处理一个用于在发送前修改CAN报文预发送。# 全局变量用于在回调函数内外传递上下文信息示例计数 g_rx_message_count 0 # 后处理事件回调当有CAN报文被发送或接收时触发 def On_CAN_EVENT(obj, p_can_msg): 处理CAN报文事件发送后/接收后。 参数: obj: 注册时传入的用户自定义对象指针c_int32。 p_can_msg: 指向TLIBCAN结构体的指针包含报文信息。 global g_rx_message_count if not p_can_msg: return # 通过contents属性访问指针指向的结构体数据 msg p_can_msg.contents g_rx_message_count 1 # 将时间戳从微秒转换为秒便于阅读 timestamp_sec msg.FTimeUs / 1_000_000.0 # 判断是发送还是接收的事件这是一个简化判断实际可根据方向位 # 注意FIsTxEvent 字段需要查看最新API文档确认 event_type TX if hasattr(msg, FIsTxEvent) and msg.FIsTxEvent else RX # 打印报文基本信息 print(f[CAN {event_type}] ID: 0x{msg.FIdentifier:03X}, f数据: {list(msg.FData[:msg.FDLC])}, f时间: {timestamp_sec:.6f}s, 计数: {g_rx_message_count}) # 预发送事件回调在CAN报文即将被发送前触发 def On_CAN_Pre_Tx_Event(obj, p_can_msg): 处理CAN报文预发送事件。 在此函数中可以修改即将发送的报文内容。 if not p_can_msg: return msg p_can_msg.contents target_id 0x100 # 我们想要修改的报文ID if msg.FIdentifier target_id: # 动态修改ID为0x100的报文的第一字节数据 original_data msg.FData[0] msg.FData[0] 0xFF # 修改为固定值0xFF print(f[Pre-TX] 修改了ID 0x{target_id:X}的报文数据。 f 字节0: {original_data} - 0x{msg.FData[0]:02X}) # 你还可以修改DLC、ID等其他字段 # msg.FDLC 8 # msg.FIdentifier 0x200这里有几个实战要点指针安全始终检查传入的指针p_can_msg是否有效非空。数据访问通过.contents访问ctypes指针指向的实际数据。性能意识尤其是在On_CAN_Pre_Tx_Event中打印日志虽然是调试利器但在高频发送场景下可能成为性能瓶颈正式环境中可考虑移除或使用更高效的日志方式。全局状态使用global关键字或可变的容器如列表、字典来在回调函数内部更新外部状态如g_rx_message_count。3. 注册、运行与资源管理让回调真正工作起来定义了回调函数还需要将其“告诉”TSMaster库并启动整个通信流程。这个过程涉及创建函数指针、注册事件、连接硬件、发送测试报文以及最重要的——确保资源被正确释放。3.1 创建函数指针与注册事件Python的ctypes库要求我们将Python函数转换为C语言兼容的函数指针才能传递给DLL。def setup_callbacks(): 创建函数指针并注册事件回调。 返回: tuple: (成功标志, 用于后续注销的回调对象列表) callback_objects [] # 用于保存c_int32对象防止被垃圾回收 obj_rx c_int32(0) # 用户自定义对象可以传递一个标识或上下文 obj_pre_tx c_int32(1) # 将Python函数转换为C函数指针 OnCANevent TCANQueueEvent_Win32(On_CAN_EVENT) OnCANpreEvent TCANQueueEvent_Win32(On_CAN_Pre_Tx_Event) # 注册后处理事件回调 ret_rx tsapp_register_event_can(byref(obj_rx), OnCANevent) # 注册预发送事件回调 ret_pre_tx tsapp_register_pretx_event_can(byref(obj_pre_tx), OnCANpreEvent) if ret_rx 0 and ret_pre_tx 0: callback_objects.extend([obj_rx, obj_pre_tx, OnCANevent, OnCANpreEvent]) print([INFO] CAN事件回调注册成功。) return True, callback_objects else: print(f[ERROR] 回调注册失败。RX: {ret_rx}, Pre-TX: {ret_pre_tx}) return False, [] # 在主函数中调用 def main(): if not safe_initialize(CallbackDemo): return if not configure_can_channel(): # 错误处理执行资源清理 finalize_lib_tsmaster() return # 硬件映射配置此处需根据你的实际硬件型号和通道修改 # 这是一个示例将软件通道1映射到TC1014设备的通道1 hw_type _TLIBBusToolDeviceType.TS_USB_DEVICE hw_subtype _TLIB_TS_Device_Sub_Type.TC1014 hw_name TC1014.encode(utf-8) app_name CallbackDemo.encode(utf-8) ret_map tsapp_set_mapping_verbose( app_name, _TLIBApplicationChannelType.APP_CAN, CHANNEL_INDEX.CHN1, hw_name, hw_type, hw_subtype, 0, # 设备索引 CHANNEL_INDEX.CHN1, True # 启用 ) if ret_map ! 0: print(f[ERROR] 硬件映射失败错误码: {ret_map}) finalize_lib_tsmaster() return print([INFO] 硬件映射配置成功。) # 配置CAN FD控制器参数如果是CAN FD网络 # tsapp_configure_baudrate_canfd(...) # 设置回调 success, cb_objs setup_callbacks() if not success: tsapp_disconnect() finalize_lib_tsmaster() return # 连接硬件 if tsapp_connect() ! 0: print([ERROR] 连接硬件失败。) finalize_lib_tsmaster() return print([INFO] 硬件连接成功。) # ... (后续发送报文和测试逻辑)3.2 发送测试报文与主循环注册好回调并连接硬件后我们可以发送一些测试报文来触发事件。# 创建并发送一个周期性的CAN报文ID: 0x100 can_msg_100 TLIBCAN(FIdentifier0x100, FDLC8, FData[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]) # 异步发送一帧 tsapp_transmit_can_async(can_msg_100) # 添加一个周期发送报文每100ms发送一次 tsapp_add_cyclic_msg_can(can_msg_100, 100) # 周期单位是毫秒 # 创建并发送另一个CAN报文ID: 0x200它不会被预发送回调修改 can_msg_200 TLIBCAN(FIdentifier0x200, FDLC2, FData[0xAA, 0xBB]) tsapp_add_cyclic_msg_can(can_msg_200, 500) print([INFO] 测试报文已开始周期发送。运行5秒...) try: # 主循环让程序运行一段时间以观察回调效果 for i in range(50): # 50 * 0.1s 5s time.sleep(0.1) # 这里可以添加其他逻辑比如检查用户输入、更新UI等 sys.stdout.write(.) sys.stdout.flush() print() # 换行 except KeyboardInterrupt: print(\n[INFO] 用户中断。)3.3 至关重要的资源清理这是很多开发者忽略但会导致内存泄漏或程序异常退出的关键一步。必须确保在程序结束前以正确的顺序释放所有资源。finally: # 无论是否发生异常都执行清理操作 print([INFO] 开始清理资源...) # 1. 停止并删除所有周期报文 tsapp_delete_cyclic_msgs() time.sleep(0.1) # 稍作等待确保最后一批周期报文处理完毕 # 2. 注销回调事件重要防止回调在库卸载后还被调用 # 注意TSMaster API可能需要特定的注销函数此处假设使用None参数注销 # 请根据实际API文档调整。如果API没有提供则跳过。 # tsapp_unregister_event_can(...) # tsapp_unregister_pretx_event_can(...) # 3. 断开与硬件的连接 tsapp_disconnect() print([INFO] 已断开硬件连接。) # 4. 最后释放TSMaster库 finalize_lib_tsmaster() print([INFO] TSMaster库资源已释放。程序退出。)这个finally块保证了即使程序运行中抛出异常或被用户中断清理工作也会被执行。正确的顺序是先停止数据流删除周期报文然后断开硬件最后释放库资源。4. 进阶技巧与常见“坑点”排查当你掌握了基础流程后下面这些进阶技巧和问题排查经验能让你写出更专业、更稳定的代码。4.1 性能优化与线程安全回调函数的执行效率如前所述预发送回调必须极快。如果需要进行复杂计算考虑将数据放入一个线程安全的队列如queue.Queue在另一个工作线程中进行处理。避免在回调中阻塞绝对不要在回调函数内部进行time.sleep()、等待锁、进行大量I/O操作。这会导致事件队列堵塞轻则数据延迟重则导致TSMaster内部缓冲区溢出丢失报文。使用生产者-消费者模式这是处理高频回调数据的经典模式。回调函数作为生产者快速将数据放入队列另一个线程作为消费者从队列中取出数据进行处理、存储或显示。import queue import threading data_queue queue.Queue(maxsize1000) # 设置一个合理的队列大小 def On_CAN_EVENT_Fast(obj, p_can_msg): 一个高效的回调只做最少的工作打包数据并放入队列。 if not p_can_msg: return msg p_can_msg.contents # 创建数据的副本或提取必要信息注意性能开销 snapshot (msg.FIdentifier, msg.FTimeUs, list(msg.FData[:msg.FDLC])) try: data_queue.put_nowait(snapshot) # 非阻塞放入 except queue.Full: print([WARNING] 数据队列已满丢弃一条CAN数据。) # 处理队列满的情况 def data_processing_worker(): 后台工作线程处理队列中的数据。 while True: try: can_id, timestamp, data data_queue.get(timeout1.0) # 在这里进行耗时的操作如写入文件、数据库、复杂计算等 # print(fProcessing ID 0x{can_id:X}...) data_queue.task_done() except queue.Empty: # 超时检查是否应该退出 if shutdown_event.is_set(): break continue # 在主函数中启动工作线程 shutdown_event threading.Event() worker_thread threading.Thread(targetdata_processing_worker, daemonTrue) worker_thread.start()4.2 常见错误与调试方法即使代码逻辑正确你也可能遇到各种运行时问题。下面是一个快速排查指南回调函数没有被调用检查注册返回值tsapp_register_event_can等函数的返回值是否为0。检查硬件连接状态回调只在硬件连接成功后生效。确保tsapp_connect()成功。检查通道映射确保软件通道正确映射到了物理硬件通道。检查总线活动确保总线上确实有报文在收发。可以先用TSMaster软件自带的监控功能确认。检查回调函数签名必须与TCANQueueEvent_Win32等类型严格匹配。程序崩溃Access Violation指针生命周期确保传递给回调注册的函数指针OnCANevent等在其被使用期间一直有效。不要让它成为局部变量然后被回收。通常将其保存在全局或类成员变量中。资源释放顺序确保在finalize_lib_tsmaster()之后绝不再尝试调用任何TSMaster API函数或访问回调数据。多线程冲突如果你在多线程环境中使用TSMaster API请查阅文档确认其线程安全性。通常对同一通道的并发API调用需要加锁。预发送回调修改无效确认报文ID检查回调函数中的ID判断逻辑是否正确。确认回调类型你注册的是tsapp_register_pretx_event_can而不是tsapp_register_event_can。检查发送方式预发送回调只对通过tsapp_transmit_can_async等API发送的报文有效。通过TSMaster软件界面手动发送的报文可能不触发。调试提示在开发初期可以在回调函数开始处添加简单的文件日志记录函数被调用的时间和参数这比print更可靠因为print输出可能因为缓冲区问题而延迟或丢失尤其是在高频回调中。4.3 扩展至CAN FD与多通道将上述CAN的示例扩展到CAN FD和多通道是直接的。原理完全相同只是使用的API函数和数据结构换成了CAN FD版本。CAN FD回调使用TCANFDQueueEvent_Win32创建函数指针使用tsapp_register_event_canfd和tsapp_register_pretx_event_canfd进行注册。数据结构使用TLIBCANFD代替TLIBCAN。注意CAN FD有更长的数据场最多64字节和独立的仲裁/数据段波特率。多通道处理你可以在一个回调函数中处理多个通道的报文。回调函数中的p_can_msg指向的结构体通常包含通道索引信息例如FChannelIndex。根据这个索引你可以在回调内部区分报文来自哪个通道并执行不同的逻辑。def On_CAN_EVENT_Multi_Channel(obj, p_can_msg): if not p_can_msg: return msg p_can_msg.contents ch_index msg.FChannelIndex # 假设这个字段存在请查阅API文档确认 if ch_index 0: # 处理通道1的报文 pass elif ch_index 1: # 处理通道2的报文 pass # ... 打印或处理报文掌握了事件回调你就解锁了TSMaster Python二次开发中最具威力的功能之一。它让你的脚本从被动的指令执行者变成了一个能主动感知和响应总线动态的智能体。从简单的数据记录到复杂的闭环测试可能性由此展开。在实际项目中我习惯将回调处理模块化与状态机、配置管理结合起来构建出能够应对各种测试场景的健壮框架。记住清晰的错误处理、严谨的资源管理和对性能的持续关注是区分业余脚本与工业级工具的关键。

相关新闻

DBeaver最新版安装指南:5分钟搞定ClickHouse连接(附阿里云Maven源配置)

DBeaver最新版安装指南:5分钟搞定ClickHouse连接(附阿里云Maven源配置)

DBeaver最新版安装指南:5分钟搞定ClickHouse连接(附阿里云Maven源配置) 对于需要在本地快速搭建数据分析或开发环境的工程师来说,一个趁手的数据库管理工具至关重要。DBeaver以其开源、免费、支持海量数据库的特性,成为…

2026/7/6 12:37:24 阅读更多 →
Ubuntu换源全攻略:从系统版本识别到一键更新(附常见报错解决方案)

Ubuntu换源全攻略:从系统版本识别到一键更新(附常见报错解决方案)

Ubuntu 软件源配置深度指南:精准识别、高效替换与实战排错 刚装好 Ubuntu,那种新系统的清爽感让人兴奋,但紧接着,一个现实问题就摆在面前:安装软件、更新系统时,那缓慢的下载速度,甚至频繁的连接…

2026/7/5 14:58:40 阅读更多 →
通义灵码插件深度体验:如何用AI助手让你的IDEA开发效率翻倍?

通义灵码插件深度体验:如何用AI助手让你的IDEA开发效率翻倍?

通义灵码:重塑IntelliJ IDEA开发体验的智能编码伙伴 作为一名长期与IntelliJ IDEA为伴的开发者,你是否也曾经历过这样的时刻:面对一个庞大而陌生的遗留代码库,感觉像是在阅读一部没有注释的天书;或者,在编写…

2026/7/6 10:12:02 阅读更多 →

最新新闻

2026年AI大模型开发指南:技术栈与学习路线

2026年AI大模型开发指南:技术栈与学习路线

1. 为什么2026年需要这份AI大模型开发指南?过去三年里,大模型技术以每月都有突破的速度迭代。我在2023年刚开始接触大模型时,GPT-3还是最先进的模型,到2025年,参数规模已经增长了100倍。这种爆炸式发展带来两个直接问题…

2026/7/6 12:37:19 阅读更多 →
Stable Diffusion 3 图像生成实战:基于《穿石棉的人》描绘未来废墟的 5 个提示词工程技巧

Stable Diffusion 3 图像生成实战:基于《穿石棉的人》描绘未来废墟的 5 个提示词工程技巧

Stable Diffusion 3 图像生成实战:基于《穿石棉的人》描绘未来废墟的 5 个提示词工程技巧当科幻文学中的"沉寂的百老汇"、"永恒的衰败"这类抽象描述遇上Stable Diffusion 3的生成能力,我们面对的不仅是技术实现问题,更是…

2026/7/6 12:35:16 阅读更多 →
字节面试复盘2026/07/03

字节面试复盘2026/07/03

复盘来自2026/07/03 字节扣子编程开发 人生首面~~~1.流式输出是怎么实现的 1. 核心原理 流式输出本质是HTTP分块长连接,区别普通一次性响应:普通接口等后端处理完返回完整JSON;流式是大模型边生成文字、后端边分段推送,前端边接收…

2026/7/6 12:35:16 阅读更多 →
TPAFE0808与MKV44F256VLH16构建多通道信号采集系统

TPAFE0808与MKV44F256VLH16构建多通道信号采集系统

1. 项目背景与核心需求在工业自动化、医疗设备和消费电子领域,多通道信号采集与系统监测一直是关键需求。TPAFE0808作为一款8通道模拟前端芯片,搭配MKV44F256VLH16这款高性能微控制器,能够构建一套稳定可靠的多通道信号处理系统。这套组合特别…

2026/7/6 12:33:13 阅读更多 →
灰度共生矩阵 (GLCM) 实战:Python 提取 4 大纹理特征,准确率提升 15%

灰度共生矩阵 (GLCM) 实战:Python 提取 4 大纹理特征,准确率提升 15%

灰度共生矩阵(GLCM)实战:Python提取4大纹理特征提升分类准确率纹理分析一直是计算机视觉领域的重要研究方向,想象一下你正在开发一个木材质量检测系统,如何让机器像经验丰富的质检员一样,通过表面纹理判断木材等级?这正…

2026/7/6 12:33:13 阅读更多 →
协方差矩阵与皮尔森相关系数:从2维到N维数据的3步可视化分析实战

协方差矩阵与皮尔森相关系数:从2维到N维数据的3步可视化分析实战

协方差矩阵与皮尔森相关系数:从2维到N维数据的3步可视化分析实战在数据科学和机器学习领域,理解变量之间的关系是建模和特征工程的基础。当我们面对高维数据集时,如何快速识别特征间的关联模式?协方差矩阵和皮尔森相关系数矩阵就像…

2026/7/6 12:33:13 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻