7. TypeScript接口

TypeScript 中的接口(Interfaces)用于定义对象的结构。它们允许开发者指定一个对象应具有哪些属性以及这些属性的类型。接口有助于确保对象遵循特定的结构,从而在整个应用中提供一致性,并提升代码的可维护性。

一、认识接口

TypeScript 是 JavaScript 的一个静态类型超集,它添加了可选的类型、类、接口以及其他功能,帮助开发者构建健壮且易于维护的应用程序。TypeScript 最强大的特性之一就是接口(interfaces),它允许你定义对象的结构,强制保持一致性,并提升代码的可读性。

(一) 什么是接口

在 TypeScript 中,接口是一种“契约”,用于定义对象的结构。它指定了一个对象必须具备的属性和方法,但不提供具体的实现。接口仅用于类型检查,在编译过程中会被移除。

使用接口有很多好处:

  • 定义对象结构:确保对象具有特定的属性和方法。
  • 提高代码可读性:清晰地展示对象应包含哪些属性和方法。
  • 强制一致性:通过确保对象遵循特定结构来防止错误发生。

以下是一个在 TypeScript 中使用接口的简单示例:

interface Car {make: string;model: string;year: number;
}
const myCar: Car = {make: "Toyota",model: "Corolla",year: 2022
};
console.log(myCar);

Car 接口:定义了 car 对象的结构,其中 makemodelyear 是必需的属性。

myCar 对象:一个符合 Car 接口结构的对象,包含指定的属性。

输出:

{ make: 'Toyota', model: 'Corolla', year: 2022 }

(二) 场景示例

1. 类中的接口

// 定义一个 Employee 接口,包含姓名、年龄和职位属性
interface Employee {name: string;age: number;position: string;
}// Manager 类实现了 Employee 接口,必须包含接口中定义的所有属性
class Manager implements Employee {name: string;age: number;position: string;// 构造函数用于初始化 name、age 和 positionconstructor(name: string, age: number, position: string) {this.name = name;this.age = age;this.position = position;}
}// 创建一个 Manager 类的实例
const manager1 = new Manager("John Doe", 35, "Project Manager");// 输出 manager1 对象
console.log(manager1);
  • Employee 接口定义了一个员工的结构,要求包含 nameageposition 属性。
  • Manager 类实现了 Employee 接口,确保它具有这些必需的属性。

输出:

Manager { name: 'John Doe', age: 35, position: 'Project Manager' }

2. 对象的接口定义

// 定义 Product 接口,包含 id、name 和 price 属性
interface Product {id: number;name: string;price: number;
}// 创建一个符合 Product 接口的对象 product
const product: Product = {id: 1,name: "Laptop",price: 1200
};// 输出 product 对象
console.log(product);
  • Product 接口规定了一个产品对象必须包含 id(数字)、name(字符串)和 price(数字)属性。
  • product 对象符合 Product 接口,包含了所有必需的属性。

输出:

{ id: 1, name: 'Laptop', price: 1200 }

3. 带有方法签名的接口

// 定义 Calculator 接口,包含两个方法的签名:add 和 subtract,均接收两个数字参数,返回数字
interface Calculator {add(a: number, b: number): number;subtract(a: number, b: number): number;
}// SimpleCalculator 类实现 Calculator 接口,提供 add 和 subtract 方法的具体实现
class SimpleCalculator implements Calculator {add(a: number, b: number): number {return a + b;}subtract(a: number, b: number): number {return a - b;}
}// 创建 SimpleCalculator 实例
const calc = new SimpleCalculator();// 调用 add 方法,输出结果 8
console.log(calc.add(5, 3));// 调用 subtract 方法,输出结果 5
console.log(calc.subtract(9, 4));
  • Calculator 接口定义了两个方法:add 和 subtract,二者都接受两个数字参数并返回一个数字。
  • SimpleCalculator 类实现了 Calculator 接口,为 add 和 subtract 方法提供了具体的逻辑实现。
8
5

(三) 使用接口的最佳实践

  • 使用接口定义对象结构:始终使用接口来定义代码中复杂对象或数据模型的结构。
  • 使用可选属性:如果某些属性可能不总是存在,可以将它们设为可选,以提高代码的灵活性。
  • 接口继承:利用接口继承,从简单接口构建更复杂的结构。
  • 使用接口定义函数签名:在定义复杂函数时,接口能帮助明确函数签名,使代码更易维护。

二、interface 和 type 的区别

在 TypeScript 中,interface 和 type 都用于定义对象的结构,但它们在灵活性和使用上有所不同。interface 是可扩展的,主要用于描述对象的形状;而 type 更加多样化,支持联合类型、交叉类型以及更复杂的类型定义。

(一) TypeScript 中的类型

TypeScript 的类型系统描述了语言支持的各种数据类型。它主要分为三大类:任意类型(Any Type)、内置类型(Built-In Type)和用户自定义类型(User-Defined Type)。TypeScript 的类型系统负责在程序运行前确保数据类型的正确性。

在这个示例中,我们定义了两个 TypeScript 类型 —— People 和 MorePeople,并使用交叉类型操作符 & 将它们组合起来。常量 people 同时实现了这两种类型,存储并输出了这个组合后的对象。

// 定义类型 People,包含 name 和 age 属性
type People = {name: string;age: number;
};// 定义类型 MorePeople,包含 email 属性
type MorePeople = {email: string;
};// 使用交叉类型将 People 和 MorePeople 组合成 CombinedPeople 类型
type CombinedPeople = People & MorePeople;// 创建符合 CombinedPeople 类型的对象 people,包含 name、age 和 email 属性
const people: CombinedPeople = {name: "FelixLu",age: 20,email: "FelixLu@gmail.com"
};// 输出 people 对象
console.log(people);

输出:

{ name: 'FelixLu', age: 20, email: 'FelixLu@gmail.com' }

(二) TypeScript 中的接口

接口(Interface)是 TypeScript 中一种语法上的“契约”,实体必须遵守该契约。接口只能声明属性、方法和事件,而不包含任何具体实现。接口定义了实现类必须遵循的标准结构。

本例展示了 TypeScript 中接口的合并(Interface Merging)特性。两个同名的 People 接口会自动合并,允许对象 people 实现所有属性(name、age、email),并输出合并后的结果。

// 创建接口 People,包含 name 和 age 属性
interface People {name: string;age: number
}// 重新声明同名接口 People,包含 email 属性,接口会自动合并
interface People {email: string;
}// 创建符合合并后接口 People 的对象 people,包含 name、age 和 email 属性
const people: People = {name: "FelixLu",age: 20,email: "FelixLu@gmail.com"
};// 输出 people 对象
console.log(people);

输出:

{ name: 'FelixLu', age: 20, email: 'FelixLu@gmail.com' }

(三) TypeScript 中 Type 和 Interface 的区别

特性

Type

Interface

定义

一组数据类型

一种语法契约

灵活性

更灵活

相较于 Type 灵活性较低

关键字

使用 type 关键字

使用 interface 关键字

命名

支持为类型创建新的名称

用于定义实体

能力

能力较少

能力更强

对象使用

本身不直接支持对象的使用

支持对象的使用

声明合并

不支持多重声明合并

支持多重声明合并

名称冲突

同名的两个类型会报异常

同名的两个接口会被合并

实现

不用于实现目标

用于类的实现和继承

联合类型

不支持实现或继承联合类型

支持实现和继承联合类型

交叉类型

可以通过组合多个类型创建交叉类型

不支持创建交叉接口

原始类型、联合类型和元组的使用

可用于原始类型、联合类型和元组

不支持其他类型的声明

虽然 TypeScript 的 type 和 interface 在某些特性上有所不同,但它们在很多方面是相似的,且彼此并不能完全取代。开发者可以根据项目的具体需求选择使用哪一种。type 和 interface 各自的灵活性和特定使用场景,使它们成为 TypeScript 开发中非常有价值的工具。

三、接口与类

在 TypeScript 中,接口定义了类必须遵守的结构,确保对象形状的一致性并促进类型检查。

  • 接口声明属性和方法,但不包含具体实现,作为类必须实现的契约。
  • 类通过 implements 关键字实现接口,并为接口中声明的成员提供具体实现。

以下是相关的方法:

(一) 类实现接口

在 TypeScript 中,类可以实现接口,以确保它遵守接口定义的特定结构。

语法:

class ClassName implements InterfaceName {// 类的属性和方法
}

一个例子:

// 定义接口 Shape,声明一个方法 calculateArea,返回数字类型
interface Shape {calculateArea(): number;
}// Rectangle 类实现 Shape 接口
class Rectangle implements Shape {width: number;height: number;constructor(width: number, height: number) {this.width = width;this.height = height;}// 实现接口中的 calculateArea 方法,计算矩形面积calculateArea(): number {return this.width * this.height;}
}// 创建 Rectangle 实例,并调用 calculateArea 方法
const rect = new Rectangle(5, 10);
console.log(rect.calculateArea());
  • Shape 接口定义了一个包含 calculateArea 方法的契约。
  • Rectangle 类实现了 Shape 接口,为 calculateArea 方法提供了具体实现。
  • 创建了一个宽为 5、高为 10 的 Rectangle 实例,并调用 calculateArea 方法计算面积。

输出:

50

(二) 类实现多个接口

在 TypeScript 中,类可以实现多个接口,从而遵守多个契约,并确保为所有指定的成员提供实现。

语法:

class ClassName implements Interface1, Interface2 {// 类的属性和方法
}

一个例子:

// 定义接口 Shape,声明方法 calculateArea,返回数字类型
interface Shape {calculateArea(): number;
}// 定义接口 Color,声明属性 color,类型为字符串
interface Color {color: string;
}// Circle 类同时实现 Shape 和 Color 两个接口
class Circle implements Shape, Color {radius: number;color: string;constructor(radius: number, color: string) {this.radius = radius;this.color = color;}// 实现接口 Shape 中的 calculateArea 方法,计算圆的面积calculateArea(): number {return Math.PI * this.radius * this.radius;}
}// 创建 Circle 实例,半径为 5,颜色为红色
const circle = new Circle(5, 'red');
console.log(`颜色: ${circle.color}`);
console.log(`面积: ${circle.calculateArea()}`);
  • Shape 接口声明了一个 calculateArea 方法,定义了计算图形面积的契约。
  • Color 接口包含一个 color 属性,规定实现该接口的类必须具有颜色属性。
  • Circle 类同时实现了 Shape 和 Color 接口,为 calculateArea 方法和 color 属性提供了具体实现。

输出:

颜色: red
面积: 78.53981633974483

四、创建带条件类型的接口

TypeScript 中的条件类型使开发者能够创建根据所遇类型自动调整行为的接口。该特性提升了代码的灵活性和适应性,尤其适用于类型可能变化的场景。

通过使用条件类型,开发者可以定义动态调整结构和约束的接口,为构建健壮且类型安全的应用提供强大工具。

(一) 使用 extends 关键字

这种方法通过使用条件类型来区分不同的类型,并根据条件有选择地扩展接口的属性。

语法:

interface InterfaceName<T> {propertyName: T extends ConditionType ? TypeIfTrue : TypeIfFalse;
}

下面的代码使用 extends 关键字和三元运算符创建了一个带条件类型的接口。

// 定义带有条件类型的接口 Vehicle,泛型参数 T
interface Vehicle<T> {// 如果 T 是 'car',则 type 属性为 'four-wheeler',否则为 'two-wheeler'type: T extends 'car' ? 'four-wheeler' : 'two-wheeler';// 如果 T 是 'car',则 wheels 属性为 4,否则为 2wheels: T extends 'car' ? 4 : 2;
}// 创建类型为 Vehicle<'car'> 的对象 car
const car: Vehicle<'car'> = {type: 'four-wheeler',wheels: 4
};// 创建类型为 Vehicle<'bike'> 的对象 bike
const bike: Vehicle<'bike'> = {type: 'two-wheeler',wheels: 2
};console.log(car);
console.log(bike);

输出:

{ type: 'four-wheeler', wheels: 4 }
{ type: 'two-wheeler', wheels: 2 }

(二) 映射类型

映射类型结合条件约束,能够根据特定条件将已有类型转换成新的接口。

语法:

type MappedTypeName<T> = {[P in T]: T extends ConditionType ? TypeIfTrue : TypeIfFalse;
};

下面的代码使用映射类型实现了带条件类型的接口。

// 定义联合类型 Fruit,包含 'apple' 和 'banana'
type Fruit = 'apple' | 'banana';// 定义映射类型 FruitProperties,泛型参数 T 是字符串数组
// 遍历数组中的每个元素 P,若 P 是 'apple',属性类型为 { color: string }
// 否则属性类型为 { length: number }
type FruitProperties<T extends string[]> = {[P in T[number]]: P extends 'apple' ? { color: string } : { length: number };
};// FruitInfo 接口继承自 FruitProperties,传入 Fruit 数组类型
interface FruitInfo extends FruitProperties<Fruit[]> {}// 创建 FruitInfo 类型的 appleInfo 对象,包含 apple 属性
const appleInfo: FruitInfo = {apple: { color: 'red' }
} as FruitInfo;// 创建 FruitInfo 类型的 bananaInfo 对象,包含 banana 属性
const bananaInfo: FruitInfo = {banana: { length: 10 }
} as FruitInfo;console.log(appleInfo);
console.log(bananaInfo);

输出:

{ apple: { color: red } } 
{ banana: { length: 10 } } 

(三) 条件类型和联合类型

在这种方法中,我们结合联合类型和条件类型,定义能够根据不同类型动态调整的接口。

type ConditionalInterface<T> = T extends ConditionType1 ? InterfaceType1 :T extends ConditionType2 ? InterfaceType2 :DefaultInterfaceType;

下面的代码演示了如何结合条件类型和联合类型,动态定义接口。

type Fruit = 'apple' | 'banana';// 定义条件类型 FruitProperties:根据不同的 T 类型返回不同的属性结构
type FruitProperties<T> = T extends 'apple' ? { color: string } :T extends 'banana' ? { length: number } :never;// 创建 appleProperties,类型为 FruitProperties<'apple'>,要求包含 color 属性
const appleProperties: FruitProperties<'apple'> = { color: 'red' };// 创建 bananaProperties,类型为 FruitProperties<'banana'>,要求包含 length 属性
const bananaProperties: FruitProperties<'banana'> = { length: 10 };console.log(appleProperties); 
console.log(bananaProperties);

输出:

{ color: 'red' }
{ length: 10 }

五、混合类型

在 TypeScript 中,混合类型(Hybrid Types)指的是将不同类型特性组合在一起的类型,例如对象、函数、数组等的结合体。混合类型可以让一个值既像函数一样被调用,又像对象一样拥有属性和方法

在 TypeScript 中,我们可以使用接口(interface)或类型别名(type alias)来定义混合类型(Hybrid Types)。这些声明可以包括:

  • 属性签名(Property Signatures):声明对象类型的属性;
  • 调用签名(Call Signatures):声明该对象可以像函数一样被调用;
  • 索引签名(Index Signatures):允许对象通过键访问其成员。

混合类型通常是以下不同类型元素的组合,包括:

  • 可调用属性(Callable properties):该对象可以作为函数被调用;
  • 属性(Properties):该对象像普通对象一样拥有属性。

这使得我们可以定义出功能灵活、可配置的对象类型,既可以调用也可以持有状态和方法。

(一) 场景示例

1. 对象-函数混合类型

在下面的示例中,Logger 接口引入了两种函数类型的混合:一种是接收消息作为参数的函数,另一种是不接收参数的函数。此外,它还暴露了一个名为 level 的属性和一个名为 setLevel 的方法。

interface Logger {(message: string): void; // 可调用签名:接受一个字符串消息作为参数level: string; // 属性:日志级别setLevel(newLevel: string): void; // 方法:设置日志级别
}function createLogger(): Logger {let logger = function (message: string) {console.log(`[${logger.level}] ${message}`);} as Logger;logger.level = "info"; // 默认级别为 infologger.setLevel = function (newLevel: string) {logger.level = newLevel; // 设置新的日志级别};return logger;
}const myLogger = createLogger();
myLogger("启动应用程序。");
myLogger.setLevel("debug");
myLogger("调试应用程序。");

输出:

[info] 启动应用程序。
[debug] 调试应用程序。

2. 数组-对象混合类型

在这个例子中,StringArray 接口既是一种数组,也是一种对象。这意味着它允许使用数字进行索引,并具有像 lengthdescription 这样的附加属性。

interface StringArray {[index: number]: string; // 使用数字索引,返回字符串length: number;          // 表示数组的长度description: string;     // 描述信息
}let myStringArray: StringArray = {0: "hello",1: "world",length: 2,description: "这个数组包含字符串。" // 中文翻译
};console.log(myStringArray[0]);           
console.log(myStringArray.description); 

输出:

hello
这个数组包含字符串。

(二) 使用场景和优点

1. 混合类型的使用场景

  • 库 API:库应使用混合类型来创建灵活且健壮的 API;例如,jQuery 对象既可以作为函数调用,也有方法和属性。
  • 事件触发器:它可能包含用于触发事件的函数,以及添加或移除监听器的方法。
  • 配置对象:配置对象可以是可调用的(即触发某些操作),同时也包含配置属性。
  • 复杂数据结构:混合类型非常适合需要支持类似对象的动态键和类似数组的数字索引的复杂数据结构。

2. 混合类型的优点

  • 灵活性:允许一个类型扮演多种角色,从而简化了适应性强的 API 的创建。
  • 类型安全:TypeScript 的类型检查可以在编译时捕获混合类型的错误。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UE 新版渲染器输出视频

安装包解压到C盘 打开UE插件 Movie Render Queue 进入UE引擎在项目设置找到 libx264 aac mp4 影片渲染队列调用出 命令行编码器安装包路径&#xff0c;序列输出路径&#xff0c;定序器不能有中文

基于用户的协同过滤推荐算法实现(Java电商平台)

在电商平台中&#xff0c;基于用户的协同过滤推荐算法是一种常见的推荐系统方法。它通过分析用户之间的相似性来推荐商品。以下是一个简单的实现思路和示例代码&#xff0c;使用Java语言。 实现思路 数据准备&#xff1a;收集用户的评分数据&#xff0c;通常以用户-商品评分矩…

LeetCode - 904. 水果成篮

题目 904. 水果成篮 - 力扣&#xff08;LeetCode&#xff09; 思路 题目本质 你有一个整数数组&#xff0c;每个元素代表一种水果。你只能用两个篮子&#xff0c;每个篮子只能装一种水果。你要在数组中找一个最长的连续子数组&#xff0c;这个子数组里最多只包含两种不同的…

发现 Kotlin MultiPlatform 的一点小变化

最近发现 Kotlin 官方已经开始首推 Idea 的社区版的 KMP 插件了. 以前有网页创建 KMP 的项目的文档也消失了. 虽然有 Android Studio 的选项. 但是却不是在默认的位置上了. 足以说明官方是有意想让大家直接使用 Idea 社区版或者专业版 所以我直接在社区版上安装 KMP 插件. 尝试…

【Photoshop】金属字体制作

新建一个空白项目&#xff0c;选择横排文字工具&#xff0c;输入想要的文件建立文字图层 选择横排文字工具选择出文字内容&#xff0c;在通知栏出点击’拾色器‘&#xff0c;设置好需要的文字颜色 图层面板右下角点击‘添加图层样式’&#xff0c;选择斜面和浮雕 样式设置为内斜…

centos 7.9 升级ssh版本 7.4p1 升级到 8.2p1

centos 7.9 升级ssh版本 7.4p1 升级到 8.2p1 1、安装包下载2、安装telnet3、安装openssl-OpenSSL_1_1_1f.tar.gz4、安装openssh-8.2p1.tar.gz5、修改ssh服务的相关配置文件6、确定可以ssh连接服务器后&#xff0c;卸载telnet&#xff0c;因为telnet不安全 本文是离线环境下升级…

stm32---dma串口发送+fifo队列框架

之前分享了一个关于gd32的fifo框架&#xff0c;这次就用stm32仿照写一个&#xff0c;其实几乎一样&#xff0c;这次说的更详细点&#xff0c;我全文都写上了注释&#xff0c;大家直接cv模仿我的调用方式即可 uasrt.c #include "stm32f10x.h" // D…

【生产就曲篇】让应用可观测:Actuator监控端点与日志最佳实践

摘要 本文是《Spring Boot 实战派》系列的终章&#xff0c;我们将探讨如何让应用真正达到**“生产就绪” (Production-Ready)** 的标准。文章的核心是可观测性 (Observability)&#xff0c;即从外部了解一个系统内部运行状态的能力。 我们将深度挖掘 Spring Boot Actuator 的…

操作系统知识(1)

操作系统的分类总结 1、批处理操作系统:单道批处理和多道批处理(主机与外设可并行) 2、分时操作系统:一个计算机系统与多个终端设备连接。将CPU的工作时间划分为许多很短的时间片&#xff0c;轮流为各个终端的用户服务。 3、实时操作系统:实时是指计算机对于外来信息能够以足…

一.Sharding分库分表-基因法+自定义多key分片实现多字段查询

前言 当下遇到这样一个场景&#xff0c;由于订单数据量达到千万级别&#xff0c;采用分库分表进行优化&#xff0c;根据订单的热查条件&#xff1a;order_no订单编号进行分表&#xff0c;但是这样带来一个问题&#xff0c;用户查询自己的订单怎么查&#xff1f;由于分片键使用…

【leetcode】543. 二叉树的直径

二叉树的直径 题目题解解释 题目 543. 二叉树的直径 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 题解 …

AI基础知识(07):基于 PyTorch 的手写体识别案例手册

目录 实验介绍 实验对象 实验时间 实验流程 实验介绍 随着人工智能技术的飞速发展&#xff0c;图像识别技术在众多领域得到了广泛应用。手写体识别作为图像 识别的一个重要分支&#xff0c;其在教育、金融、医疗等领域具有广泛的应用前景。本实验旨在利用深度 学习框架 PyTorc…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…

信号(瞬时)频率求解与仿真实践(2)

引言 本文是信号(瞬时)频率求解与仿真实践专题的第二篇文章&#xff0c;在上一篇博文 [1]信号(瞬时)频率求解与仿真实践(1)-CSDN博客中&#xff0c;我构建了信号瞬时频率求解的基本框架&#xff0c;并且比较详细地讨论了瞬时频率法。这篇博文探讨适用于信号瞬时频率求解的另一种…

Linux运行发布jar文件携带哪些参数

在 CentOS 8 上运行发布的 JAR 文件时,可以根据不同需求携带以下参数: 1. 基本运行方式 bash 复制 下载 java -jar your-application.jar 2. 常用 JVM 参数 参数说明-Xms256m初始堆内存大小(如 256MB)-Xmx1024m最大堆内存大小(如 1GB)-XX:MaxMetaspaceSize=256m元空间…

在GIS 工作流中实现数据处理(4)

结果输出与可视化 最后&#xff0c;我们将统计结果输出为一个 Excel 文件&#xff0c;并在 ArcMap 中对城市中心区域的土地利用情况进行可视化展示。 import pandas as pd# 将统计表格转换为 pandas DataFrame df pd.read_csv(statistics_table, sep"\t")# 输出为…

【术语解释】网络安全((SAST, DAST, SCA, IAST),Hadoop, Spark, Hive 的关系

## OWASP Top 10等 OWASP Top 10&#xff1a;OWASP (Open Worldwide Application Security Project&#xff0c;开放全球应用程序安全项目) Top 10 是一份由全球安全专家定期更新的报告&#xff0c;列出了当前 Web 应用程序面临的十大最关键安全风险。 它是一个广受认可的意识文…

NY197NY205美光闪存固态NY218NY226

NY197NY205美光闪存固态NY218NY226 美光科技作为全球领先的半导体存储解决方案供应商&#xff0c;其闪存固态硬盘&#xff08;SSD&#xff09;产品线一直备受业界关注。NY197、NY205、NY218和NY226是美光近期推出的几款重要固态硬盘型号&#xff0c;它们在性能、容量和适用场景…

MinHook 对.NET底层的 SendMessage 拦截真实案例反思

一&#xff1a;背景 1. 讲故事 上一篇我们说到了 minhook 的一个简单使用&#xff0c;这一篇给大家分享一个 minhook 在 dump 分析中的实战&#xff0c;先看下面的线程栈。 0:044> ~~[138c]s win32u!NtUserMessageCall0x14: 00007ffc5c891184 c3 ret 0:061&g…

qt配合海康工业相机取图开发

1.最近开发海康工业相机&#xff0c;做取图demo 2.在MVS运行目录下找到Development文件夹&#xff0c;找到下图两个文件夹一个是头文件一个是库文件 3.引用到qt项目中 4.下面是头文件跟源文件 头文件 #ifndef MVSCAMERA_H #define MVSCAMERA_H#include <QObject> #incl…