windows驱动注册中断服务程序

2023-05-16

一个驱动程序的标准中断服务例程的必要功能和建立一个ISR的需求。

1.1 ISR需求

一个产生中断的物理设备的所有驱动程序必须有一个ISR。中断服务例程由内核定义如下:

BOOLEAN

( *PKSERVICE_ROUTINE )   (

      IN PKINTERRUPT Interrupt,

      IN PVOID ServiceContext

     );

ISR运行在DIRQL上,特别是在驱动程序用IoConnectInterrupt注册其ISR时说明的SynchronizeIrql层上。当驱动程序的ISR运行时,所有带一个中等或较低IRQL值的中断被当前处理器所屏蔽。

当然,另一个带有一个较高的系统分配的DIRQL的设备可以中断,或者一个高IRQL系统中断可以在任何时间发生在Windows NT/Windows 2000机器上。

记住以下情况:

§ 一个驱动程序的ISR是可中断的。

因为ISR运行在一个相对高的、系统分配的DIRQL上,因此在当前处理器上用一个中等或较低的IRQL屏蔽中断,ISR应尽可能快的返回控制。

DIRQL运行一个ISR限制了该ISR可以调用的支持例程。关于IRQL管理的更多信息,见第16章。关于任何特定支持例程都能被调用的IRQL的说明信息,见在线DDK。

1.1.1 ISR性能

Windows NT/Windows 2000在驱动程序ISR方面完全不同于其他一些操作系统。在Windows NT/Windows 2000系统上,如果其ISR能尽可能快的返回控制,而不是试图保持对CPU的控制并在其ISR中做尽可能多的I/O处理,尤其是在SMP机器上,那么驱动程序会有更好的表现。

反之,ISR应从中断处停止设备,并保存一切必要的关于导致中断的操作的状态信息或该操作的环境。ISR应在常驻内存中保存这些信息或环境,这类内存通常位于设备扩展中。这时,它应对驱动程序的DpcForIsr例程或一个CustomDpc排队以完成这个位于一个较低的IRQL(通常是IRQL DISPATCH_LEVEL)上的操作。

ISR返回一个Boolean,表明驱动程序的设备是否产生中断。对于共享一个中断向量或DIRQL的设备的驱动程序,每个ISR一旦确定其设备不是中断源,就应返回FALSE。

1.1.2 附加的需求的驱动程序例程

所有拥有一个ISR的驱动程序也必须拥有DpcForIsr或CustomDpc例程。驱动程序也可以有附加的CustomDpc例程,以用来完成特定的中断驱动的I/O操作。

如果任何驱动程序例程与驱动程序的ISR分享数据、设备寄存器或环境信息,该驱动程序还必须有一个或多个SynchCritSection例程。

ISR运行在比DpcForIsr或CustomDpc例程更高的IRQL上。因此,在一台Windows NT/Windows 2000单处理器的机器上,ISR必须在DpcForIsr或CustomDpc例程执行之前返回。当然,在一台SMP机器上,ISR和DpcForIsr(或CustomDpc)可以并行运行。

1.1.3 建立一个ISR

驱动程序通过在设备启动时调用IoConnectInterrupt注册其ISR。驱动程序在处理一个PnP IRP_MN_START_DEVICE请求时作为最终步骤应连接中断。

每个拥有一个ISR的驱动程序必须为至少一个中断对象指针提供常驻内存。通常,该指针被存放在代表产生中断的物理设备的设备对象的设备扩展中。如果驱动程序创建一个控制器对象,中断对象指针可以存放在控制器扩展中,或者它可以存放在由驱动程序分配的,非页式缓冲池中。

如果下列两者之一为真,驱动程序必须为中断自旋锁提供存储空间以连接其所有设备的所有中断对象:

§ 驱动程序有一个单独ISR为两个或多个设备处理不同向量的中断。

§ 驱动程序的ISR处理一个在多个向量上中断的设备

驱动程序在注册其ISR之前必须通过调用KeInitializeSpinLock初始化中断自旋锁。驱动程序也必须为它处理的、与中断对象指针一样多的IRQ提供存储区间。

1.2 ISR基本功能

在入口处,ISR被赋予一个指向驱动程序的中断对象的指针和一个指向驱动程序在调用IoConnectIntertupt时建立的任意区域的ServiceContext指针。大多数驱动程序设置ServiceContext指针以代表产生中断的物理设备的设备对象或者该设备对象的设备扩展。在设备扩展中,驱动程序可以为驱动程序的DpcForIsr例程设置状态信息,DpcForIsr例程通常进行几乎所有的I/O处理以满足每个导致设备中断的请求。

在没有重叠设备I/O操作的驱动程序中,ISR应做以下工作:

1.确定中断是否为假。如果是的话,立即返回FALSE以使中断设备的ISR迅速被调用。否则,继续中断处理。

2.从中断处停止设备。

3.收集所有DpcForIsr(或CustomDpc)例程需要用来完成为当前操作的I/O处理的环境信息。

4.存放该环境信息于DpcForIsr或CustomDpc例程可访问的区域,通常在处理当前导致中断的I/O请求的目标设备对象的设备扩展中。

5.如果驱动程序有一个DpcForIsr例程,用指向当前IRP、目标设备对象和存储的环境信息的指针调用IoRequestDpcIoRequestDpcDpcForIsr例程排队以便IRQL一低于处理器上的DISPATCH_LEVEL就运行。

如果驱动程序有一个CustomDpc例程,用一个指向DPC对象(与CustomDpc例程连接)的指针和指向任何保存的环境(CustomDpc例程将需要它来完成操作)的指针调用KeInsertQueueDpc。通常,ISR也传送指向当前IRP的指针与目标设备对象。一旦IRQL低于处理器上的DISPATCH_LEVEL ,CustomDpc例程便运行。

6.返回TRUE以表明其设备产生中断。

通常,一个ISR不做实际的I/O处理以满足一个IRP。相反,它从中断处停止设备,建立必要的状态信息,然后将驱动程序的DpcForIsr 或 CustomDpc排队以便进行任何满足当前导致设备中断请求的必要I/O处理。

考虑以下实现方针:

§ 为了获得可能最短的间隔,一个ISR必须运行于DIRQL

根据上述策略可以为机器中的所有设备增加I/O流量,因为运行于DIRQL屏蔽了所有系统已经分配了一个较低或中等IRQL值的中断。

驱动程序的中断对象的SynchronizeIrql(在驱动程序调用IoConnectInterrupt时被指定)确定驱动程序的ISR与SynchCritSection例程在其上运行的DIRQL。

当一个驱动程序的StartIo例程用驱动程序的SynchCritSection例程调用KeSynchronizeExecution时,该调用者也传送指向与ISR相连的中断对象的指针。因此,来自设备的中断被屏蔽在处理器运行的SynchCritSection例程上。与此同时,KeSynchronizeExecution持有与中断对象相连的中断自旋锁,以使ISR不能从另一个处理器访问设备寄存器或者设备扩展中共享的状态,直到驱动程序的SynchCritSection例程返回控制。

关于使用一个中断自旋锁的KeSynchronizeExecution的调用者的更多信息,见第16章的“使用自旋锁”。

1.3 ISR重叠I/O操作功能

当Windows NT/Windows 2000 SMP机器内的ISR和DpcForIsr(或CustomDpc)可以并行运行时,只有代表DpcForIsr或CustomDpc例程的DPC对象的一个实例可以为在任何给定的时刻执行而被排队。

如果相同DPC对象在DpcForIsr(或CustomDpc)例程运行之前通过一个ISR不止一次地排队,相关DpcForIsr或CustomDpc例程仅被调用一次。如果DPC对象在DpcForIsr(或CustomDpc)运行时排队,该例程的两个实例可以在Windows NT/Windows 2000 SMP机器内并行运行。

因此,任何在其设备上重叠I/O操作的驱动程序必须拥有DpcForIsr和/或CustomDpc例程,在这些例程被调用时它们可以完成多个IRP。对于驱动程序的ISR的基本要求与没有重叠I/O操作的设备驱动程序一样。见“ISR基本功能”。

当然,如果一个驱动程序重叠I/O操作,其ISR必须为DpcForIsr或CustomDpc例程设置附加状态。附加状态包括一个关于DPC例程需要完成而没有完成的请求的数量以及相关的环境信息。此外,如果ISR在DPC运行之前被调用以处理另一个中断,ISR必须小心不要覆盖为没有完成的请求存储的环境信息。

因为驱动程序的DPC例程与 ISR共享该状态,其DPC例程必须用一个系统提供的SynchCritSection例程调用KeSynchronizeExecution以访问代表每个DPC例程的共享状态。

关于这些例程的更多信息,见第9章“DpcForIsr和CustomDpc例程”。关于ISR和为ISR排队的DPC互动的更多信息,见第16章的“使用自旋锁”。

用DDK做的驱动中,中断为什么不能实现
我做的是PCI的驱动,用VC6 DDK来实现。板卡桥芯片用的是9052做的驱动中设置中断可是没有反应这是为什么呢?将9052的 LINTi1接了个开关,模拟实现中断的电平输入。相关程序如下:

//获取中断资源
case CmResourceTypeInterrupt:
irql = (KIRQL) resource->u.Interrupt.Level;
vector = resource->u.Interrupt.Vector;
affinity = resource->u.Interrupt.Affinity;
mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED)? Latched : LevelSensitive;
irqshare = resource->ShareDisposition == CmResourceShareShared;


//连接中断
NTSTATUS status = IoConnectInterrupt(&pdx->InterruptObject, (PKSERVICE_ROUTINE) OnInterrupt,
(PVOID) pdx, NULL, vector, irql, irql, Latched, TRUE, affinity, FALSE);

//中断服务例程
BOOLEAN OnInterrupt(PKINTERRUPT InterruptObject, PDEVICE_EXTENSION pdx)
{ // OnInterrupt

//关中断
UCHAR HSR = READ_PORT_UCHAR(0x4c+pdx->portbase0);
KdPrint(("==============readHSRinterrupt!!!\n"));
HSR = HSR&0xFE;
WRITE_PORT_UCHAR(0x4c+pdx->portbase0,HSR);

KdPrint(("==============interrupt!!!\n"));

//恢复中断信号电平
//WRITE_REGISTER_UCHAR((PUCHAR)pdx->MemBar1+0x400000,0x10);
HSR = READ_PORT_UCHAR(0x4c+pdx->portbase0);
HSR = HSR|0x01;
WRITE_PORT_UCHAR(0x4c+pdx->portbase0,HSR);

IoRequestDpc(pdx->fdo, NULL, pdx);

return TRUE;
}

///WDMDeviceIOControl的事件响应
case IOCTL_ENABLE_INT:
{
//允许中断
UCHAR HSR = READ_PORT_UCHAR((PUCHAR)(0x4c+pdx->portbase0));
HSR = HSR | 0x01;

WRITE_PORT_UCHAR((PUCHAR)(0x4c+pdx->portbase0),HSR);

}
break;

//应用程序调用
DeviceIoControl(handle, IOCTL_ENABLE_INT, NULL, 0, NULL, 0, &dwReturn, NULL);

中断请求级(IRQL)

为了将不同CPU体系中不同的处理硬件优先级方法统一起来,NT使用了抽象的CPU优先级方案。即中断请求级。
IRQL是一个数,定义了CPU当前活动的重要性。
HIGHEST_LEVEL机器检查和总线错误(硬件)
POWER_LEVEL电源失效中断(硬件)
IPI_LEVEL多处理器系统处理器之间的门铃(硬件)
CLOCK2_LEVEL内部时钟2(硬件)
CLOCK1_LEVEL 内部时钟1(硬件)
PROFILE_LEVEL轮廓文件定时器(硬件)
DIRQLs IO设备中断的平台相关的级数(硬件)
DISPATCH_LEVEL线程调度器和延迟过程调用执行(软件)
DPC例程都是在IRQL=DISPATCH_LEVEL执行的,相当于ISR(中断服务例程)的一个延续,
伴随着ISR一起注册。
执行顺序:

执行I/O和中断------->ISR---------->DPC--------->I/O完成例程(IOCompleteRequest)--->APC(异步过程调用)

DPC对象从最终用户角度有两种:DpcForIsrCustomDPC。前者是与设备驱动对象(Device Object)绑定的;后者则由驱动自行维护。但从实现上来说,只有一种DPC对象存在,DpcForIsr所涉及的维护函数,实际上都是对CustomDPC的一个封装而已。
DPC是线程无关的,只有内核态的,这点不像APC
APC_LEVEL异步过程调用执行(软件)
PASSIVE_LEVEL一般的线程执行级(软件)
Dispatch例程的IRQLPASSIVE_LEVEL级别

看看下面的代码有什么问题?***_Read是一个Read例程。

NTSTATUS ***_Read(IN PDEVICE_OBJECT pFdo,IN PIRP Irp)

{

       ....

       KIRQL oldirql;

       …..

       // pdx->ReadBufferLock是在设备对象扩展里面的KSPIN_LOCK变量。

       KeAcquireSpinLock(&pdx->ReadBufferLock,&oldirql);

       ulBytesInReadBuffer = pdx->BytesInReadBuffer;

       KeReleaseSpinLock(&pdx->ReadBufferLock,oldirql);

       …..

}

通常Dispatch_readIRP_MJ_READ的处理例程,它运行在PASSIVE_LEVEL级别。但是当调用了KeAcquireSpinLock了之后,它就运行在DISPATCH_LEVEL级别了,这时是不能访问paged内存的。所以这段代码有可能会导致Windows蓝屏。

再看看下面这段代码会不会有问题?有什么问题?

NTSTATUS ***_DispatchClose(IN PDEVICE_OBJECT pFdo,IN PIRP Irp)

{

       …..

       KeAcquireSpinLock(&pdx->lkThread,&eOldIrqLevel);-

       if (pdx->thread)

       {

              ….

              KeWaitForSingleObject(pdx->thread,Executive,KernelMode,FALSE,NULL);

              ….

       }

       KeReleaseSpinLock(&pdx->lkThread, eOldIrqLevel)

…..

}

通常DispatchClose例程是运行IRQL等于PASSIVE_LEVEL,这是可以任意调用KeWaitForSingleObject,但是当调用KeAcquireSpinLock之后,IRQL升级到DISPATCH_LEVEL。这时再调用KeWaitForSingleObject来无限期等待,会导致dead lock,因为大家都是处在DISPATCH_LEVEL例程,别的例程可能得不到机会来设置KeWaitForSingleObject等待的事情,所以会导致dead lock

IoConnectInterrupt

IoConnectInterrupt的目的是为设备驱动程序注册一个ISR(中断服务例程),使得它可以再设备在指定的处理器上产生中断的时候被调用。

NTSTATUS

IoConnectInterrupt(

OUT PKINTERRUPT *InterruptObject,//指向驱动程序提供的中断对象存储地址,该参数随后要传递给KeSynchronizeExecution。

OUT PKSERVICE_ROUTINE ServiceRoutine,//中断服务例程的入口

IN PVOID ServiceContext,//指向驱动指定的即将传递给ISR的参数,ServiceContext必须在常驻内存中,可以是驱动程序创建的设备驱动的设备扩展,也可以是驱动创建的控制对象的控制拓展,还可以是设备驱动分配的非分页内存。

IN PKSPIN_LOCK SpinLock OPTIONAL,//指向已经初始化的自旋所,驱动程序负责自旋所的存储,并且该自旋所将用来同步被驱动程序其它例程共享的数据的访问,该参数在ISR处理多个中断向量或者驱动程序包含不止一个ISR时需要设置,否则,驱动程序不需要为中断自旋所分配存储空间,参数设置为NULL。

IN ULONG Vector,//输入获取的中断向量

IN KIRQL Irql,//输入获取的中断优先级DIRQL

IN KIRQL SynchronizeIrql,//指明ISR执行所在的DIRQL,当ISR需要处理多个中断向量或者驱动程序有多个ISR的时候,该值选择全部中断资源的u.Interrupt.Level中的最高值,否则和上面的Irql变量相等。

IN KINTERRUPT_MODE InterruptMode,//电平触发或者边沿触发

IN BOOLEAN ShareVector,//指明中断向量是否是可共享的。

IN KAFFINITY ProcessorEnableMask,//指定一个KAFFINITY值,用来说明设备中断可以在什么样的处理器平台上发生。

IN BOOLEAN FloatingSave //指明是否需要保存设备中断时的浮点堆栈,在X86平台下,该值必须是FALSE。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

windows驱动注册中断服务程序 的相关文章

  • 批量设置命令的输出和错误以分隔变量

    在Windows 7批处理 cmd exe命令行 中 我试图将命令的标准输出 stdout 和标准错误 stderr 重定向到单独的变量 因此第一个变量设置为输出 第二个变量设置为输出 变量设置为错误 如果有 而不使用任何临时文件 我已经尝
  • Unix 命令“host” - Windows 中有等效命令吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在一台 Windows 7 机器上 按照本文指示我使用 Unix 命令 host https devcenter heroku com
  • 在 C# 中使用反射列出枚举中的值

    我正在尝试使用反射来列出一个 Visual Studio 解决方案内的各个项目中的一些类的公共成员和方法 我尝试访问的所有类都是 C 的 并且它们都是从 C 类访问的 我用来进行这些调用的代码如下 public void PopulateE
  • 在 wampserver 2.2 上安装 php_imagick.dll PHP 扩展

    我使用的是 32 位操作系统的 Windows 7 我安装了 ImageMagick 6 8 7 Q16Link https www imagemagick org script download php windows我能够从命令行 转换
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 使用 BitmapEncoder 生成时如何使 GIF 循环重复

    我能够使用 BitmapEncoder C WinRT 创建动画 gif 但是 我一直无法弄清楚如何让GIF循环回来并从头开始 没有尝试太多 因为我不确定要尝试什么 搜索了更多要在 GIF 上设置的属性 但找不到任何相关内容 好吧 终于能弄
  • opencv人脸检测示例

    当我在设备上运行应用程序时 应用程序崩溃并显示以下按摩 java lang UnsatisfiedLinkError 无法加载 detector based tracker findLibrary 返回 null 我正在使用 OpenCV
  • 开发者可以在 Windows 应用程序中使用 iCloud 吗?

    开发人员可以使用 Apple 的 iCloud API 在 Mac OS X 和 iOS 上的不同版本的应用程序之间同步应用程序数据 如果开发人员拥有 Windows 版本的应用程序 该版本是否也可以使用 iCloud 将应用程序数据与 M
  • 将文件夹中的所有文件及其所有子文件夹移动到一个大文件夹中 - windows xp

    我有一个文件夹 c downloads ffme 里面有很多子文件夹 每个子文件夹中都有不同数量的文件 我想将所有这些单独的文件合并到一个大文件夹中 同时将它们从子文件夹中删除 我希望最终得到一个包含大量文件的文件夹 但没有子文件夹 我怎样
  • 在运行时,我如何判断我是否在 WinXP+ 上? win32

    我正在进行一些 win32 字符串 API 调用 并假设字符串以宽字符串形式出现 这在 XP 和更高版本上有效 我该如何断言这一点 这是运行时检查还是编译时检查 我做错了吗 这是一个例子 typedef std basic string
  • 在 Windows 7 上的 Sourcetree 中比较 Word docx 文件

    我一直在尝试获取在 Windows 7 上的 Sourcetree 中工作的 Word docx 文件的文本差异 我已按照此处的说明进行操作将 Microsoft Word 与 git 结合使用 http blog martinfenner
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将
  • VB - 以隐式方式链接 DLL

    我正在开发 VB6 图形界面 并且需要隐式链接到 DLL 这样做的动机来自于我上一个问题 https stackoverflow com questions 5194573 有问题的 DLL 使用静态 TLS declspec thread
  • 为什么 fopen 无法打开已存在的文件?

    我在 Windows XP 上使用 Visual Studio 6 是的 我知道它很旧 构建 维护 C DLL 我遇到了 fopen 无法打开现有文件的问题 它总是返回 NULL 我试过了 通过将 errno 和 doserrno 设置为零
  • 导致崩溃转储的 Java 错误的解决方法

    我开发的一个程序偶尔会由于这个错误而导致 JVM 崩溃 http bugs java com bugdatabase view bug do bug id 8029516 http bugs java com bugdatabase vie
  • git 认为文件已更改

    我在一台机器上对一个项目做了一些工作 然后推送到 github 在另一台机器上克隆并做了一些工作 然后推送 然后我回到第一台机器并做了一个pull 现在 第一台机器认为项目中最初的所有文件都已更改 我试过了 git checkout f a
  • 可以读取目标文件吗?

    我很好奇 obj文件 我几乎不知道它们是什么 或者它们包含什么 所以我用 Vim 文本编辑器打开它们 我在里面发现了一种类似外星人的语言 有什么办法可以理解它们代表什么以及它们的内容是什么 另外 它们的用途是什么 Thanks Sure 但
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • 如何使用 Win32 API 与 com 端口 (RS232) 通信

    我正在尝试使用 win32 API 与 com 端口对话 我找到了这个http www robbayer com files serial win pdf http www robbayer com files serial win pdf

随机推荐

  • WM_QUIT,WM_CLOSE区别[转]

    总结 我们要使用代码关闭程序的话 应该向窗口发送WM CLOSE或者直接调DestroyWindow HWND 函数 默认情况下WM CLOSE的消息响应就是调用DestroyWindow HWND 函数 所以我们直接调用也达到一样的效果
  • ESP32设备驱动-LIS3DSH加速度传感器驱动

    LIS3DSH加速度传感器驱动 文章目录 LIS3DSH加速度传感器驱动 1 LIS3DH介绍 2 硬件准备 3 软件准备 4 驱动实现 1 LIS3DH介绍 LIS3DSH 是一款超低功耗高性能三轴线性加速度计 属于 纳米 系列 具有嵌入
  • 66老师推荐书单

    应用词汇 四级 星火英语 新要求大学英语词汇星火式巧记速记 精华本 附MP3 光盘1 张 http product dangdang com 23315816 html 词典 柯林斯COBUILD 高阶英语学习词典 英语版 http pro
  • NetAssist 网络助手

    电脑上的网络助手找不到了 xff0c 百度搜各种不能用的和下载要积分啊什么的 xff0c 真是现在鸟大了什么林子都有 xff0c 人家开发者都还免费提供软件的使用 xff0c 你一个使用者居然还拿别人的东西赚积分 xff0c 真TM恶心 x
  • 64位的linux装的hadoop是32位的,需要手工编译

    64位的linux装的hadoop是32位的 coco by coco 2014 07 02 64位的linux装的hadoop是32位的 xff0c 需要手工编译 遇到的问题描述 xff1a root 64 db96 hadoop had
  • Unable to preventDefault inside passive event listener due to target being treated as passive.

    最近做项目经常在 chrome 的控制台看到如下提示 xff1a Unable to preventDefault inside passive event listener due to target being treated span
  • GBK 编码

    GBK编码范围 xff1a 8140 xff0d FEFE xff0c 汉字编码范围见第二节 xff1a 码位分配及顺序 GBK编码 xff0c 是对GB2312编码的扩展 xff0c 因此完全兼容GB2312 80标准 GBK编码依然采用
  • 子类能否重写父类的静态方法?

    今天在看到了一道面试题 xff0c 题目是一道代码阅读题 xff0c 问下面的代码输出结果是什么 xff1f 我最开始的理解 xff1a 上面的代码我们可以看到 xff0c 上面的类中有两个内部类Sub和Super xff0c Sub继承了
  • docker build命令详解

    docker build命令用于根据给定的Dockerfile和上下文以构建Docker镜像 docker build命令的使用格式 xff1a docker build span class token punctuation span
  • Blazor 从入门到放弃

    Blazor 从入门到放弃 Intro Blazor 是微软在 NET 里推出的一个 WEB 客户端 UI 交互的框架 xff0c 使用 Blazor 你可以代替 JavaScript 来实现自己的页面交互逻辑 xff0c 可以很大程度上进
  • WPF知识学习

    RelativeSource 61 RelativeSource AncestorType 61 x Type Window 是一种 WPF XAML 绑定方式 xff0c 它表示要从当前控件的父级元素中找到类型为 Window 的元素 x
  • STM32H7并行读取AD7606数据以及片内AD值不准解决办法

    一 硬件 先了解一下AD7606 xff0c 16位 xff0c 单电源 xff0c 200k采样率 xff0c 8路 xff0c 除了贵没有其他缺点 xff0c 数据相当的稳 xff0c 一个5V供电 xff0c 不用运放的情况下采集电压
  • C#表达式树解析步骤

    C 表达式树是一种将 C 代码表示为对象树的方式 xff0c 它提供了一种在运行时动态构建和执行代码的能力 表达式树可以用于构建 LINQ 查询 动态生成代码 ORM 框架等场景 表达式树的解析过程可以分为两个步骤 xff1a 构建表达式树
  • FluentValidation使用示例

    FluentValidation 是一个 NET 平台下的验证库 xff0c 用于验证对象的属性是否符合预期的规则 它提供了一种简洁的方式来编写验证规则 xff0c 支持链式编程 xff0c 可以轻松地构建复杂的验证逻辑 在 NET 6 中
  • 超简单BeautifulSoup版Csdn博客(摘要视图)爬虫

    csdnSpider py代码 import bs4 import requests origin 61 span class hljs string 39 http blog csdn net 39 span user agent 61
  • C#版本和.NET版本以及VS版本的对应关系

    之所以在这里分享这个对应关系 xff0c 是因为在C 基础知识系列的文章发布之后 xff0c 有些初学者对 NET版本和C 语言特性之间的对应关系有点不清楚 xff0c 有时候会弄混淆了 并且通过这个对应关系 xff0c 也可以帮助大家对C
  • SQLServer创建索引的5种方法

    前期准备 xff1a span class hljs operator span class hljs keyword create span span class hljs keyword table span Employee ID s
  • 正则 ?= 用法

    文本 xff1a span class hljs tag lt span class hljs title br span gt span 您好 xff0c 非常好 xff0c 很开心认识你 span class hljs tag lt s
  • 正则表达式(匹配第一个花括号)

    学习正则 xff0c 工作中使用正则让我对 有了新的认知 xff1a 正则中 匹配输入字符串的开始位置 xff0c 除非在 方括号表达式中使用 xff0c 此时表示不接受该字符集合 废话不多说 xff0c 直接看栗子吧 xff0c 如下图所
  • windows驱动注册中断服务程序

    一个驱动程序的标准中断服务例程的必要功能和建立一个ISR的需求 1 1 ISR需求 一个产生中断的物理设备的所有驱动程序必须有一个ISR 中断服务例程由内核定义如下 xff1a span class hljs built in BOOLEA