认识非托管动态链接库

2023-09-12 14:16:39

一、非托管动态链接库

    1、非托管动态链接库(Unmanaged Dynamic Link Library,简称DLL)
        是一种包含可执行代码和数据的二进制文件,它被设计为在操作系统级别上执行。与托管代码不同,非托管DLL是使用原生机器代码编写的,并且不依赖于特定的运行时环境(如.NET Framework或.NET Core)。

        非托管DLL通常由C、C++或其他低级语言编写,并且可以在多个编程语言和平台上使用。它们提供了对操作系统API、硬件驱动程序和其他系统级功能的访问。


    2、使用非托管DLL可以实现以下功能:

        (1)访问操作系统级别的功能:
            非托管DLL可以直接调用操作系统提供的API,访问底层功能,如文件操作、网络通信、图形处理等。

        (2)调用硬件驱动程序:
            非托管DLL可以与硬件设备进行交互,如打印机、摄像头、传感器等。

        (3)提供性能优势:
            由于非托管DLL是使用原生机器代码编写的,它们通常比托管代码执行速度更快,对于对性能要求较高的任务,可以使用非托管DLL来实现。


    3、在使用非托管DLL时,需要注意以下几点:

        (1)平台兼容性:
        非托管DLL是特定于操作系统和硬件平台的,因此需要根据目标平台选择正确的DLL版本。

        (2)内存管理:
        非托管DLL使用自己的内存管理机制,可能需要手动分配和释放内存,需要小心处理内存泄漏和访问冲突的问题。

        (3)安全性:
        非托管DLL可以直接访问系统资源,因此需要小心处理安全性问题,避免潜在的漏洞和攻击。

        总之,非托管动态链接库是一种使用原生机器代码编写的二进制文件,用于访问操作系统级别的功能和提供性能优势。它们在许多编程语言和平台上都有广泛的应用。

二、user32.dll


    1、user32.dll是Windows操作系统中的一个非托管动态链接库(DLL),它包含了许多用户界面相关的函数和功能。

        在C#中,我们可以使用P/Invoke机制来访问和调用user32.dll中的函数。通过在C#代码中声明这些函数的签名,并使用 DllImport 特性来指定user32.dll的路径和函数名,我们可以在C#中调用user32.dll中的函数。

        这样,我们可以使用user32.dll提供的函数来实现与用户界面相关的操作,如创建和管理窗口、处理鼠标和键盘输入、显示消息框等。user32.dll是Windows操作系统的一部分,因此它在所有安装了Windows的计算机上都可用。


    2、在 Windows 系统中,user32.dll 文件通常位于以下目录之一

        C:\Windows\System32:这是最常见的 DLL 文件存放目录,包含了许多系统级别的 DLL 文件。
        C:\Windows\SysWOW64:这是用于存放 32 位应用程序所需的 32 位 DLL 文件的目录。请注意,即使在 64 位系统上,32 位应用程序仍然使用这个目录来查找其所需的 32 位 DLL 文件。
        
        不同版本目录位置不同。

三、如何调用非托管动态链接库


    1、C#中使用非托管动态链接库(DLL),您可以使用平台调用(Platform Invocation Services,简称P/Invoke)机制。下面是使用P/Invoke的一般步骤:

        (1)导入DLL:使用 DllImport 特性声明非托管DLL中的函数。在特性中,指定DLL的路径和函数名。
        [DllImport("yourDLL.dll")]
        public static extern returnType functionName(parameters);

        (2)声明函数签名:在C#代码中声明与非托管DLL中函数相对应的函数签名。确保参数类型和返回类型与DLL中的函数匹配。
        public static extern returnType functionName(parameters);

        (3)调用函数:在C#代码中调用声明的函数。
        returnType result = functionName(arguments);


    2、注意事项:

        - 非托管DLL的路径应该是绝对路径或者位于系统路径(如Windows\System32)下。
        - 参数和返回类型应该与非托管DLL中函数的定义一致。
        - 非托管DLL中函数的调用约定(calling convention)可能需要进行显式的指定,如 StdCall 或 Cdecl。

        需要注意的是,使用非托管DLL需要小心处理内存管理、安全性和平台兼容性等问题。确保正确释放内存、处理异常和错误,并确保在不同的操作系统和体系结构上都能正常工作。

        另外,有些非托管DLL可能提供了专门为C#等托管语言编写的托管包装器DLL,这些包装器DLL提供了更方便的面向对象的API,可以更容易地与非托管DLL进行交互。在这种情况下,您可以直接引用这些托管包装器DLL,而不需要使用P/Invoke来调用非托管DLL中的函数。

        总结起来,使用P/Invoke机制可以在C#中访问和调用非托管动态链接库中的函数。通过声明函数签名,并使用 DllImport 特性指定DLL的路径和函数名,您可以在C#代码中调用非托管DLL中的函数。    

四、实例


    1、模拟按下Alt+Tab键

        /// <summary>
        ///
        /// </summary>
        /// <param name="bVk">模拟的键</param>
        /// <param name="bScan">保留参数,0</param>
        /// <param name="dwFlags">按键标志,0按下,2释放</param>
        /// <param name="dwExtraInfo">保留,0用(UIntPtr.Zero)表示</param>
        [DllImport("user32.dll")]
        private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);

        private void BtnStart_Click(object sender, EventArgs e)
        {
            keybd_event((byte)Keys.Menu, 0, 0, UIntPtr.Zero);//按下alt
            keybd_event((byte)Keys.Tab, 0, 0, UIntPtr.Zero);//按下tab
            keybd_event((byte)Keys.Menu, 0, 2, UIntPtr.Zero);//松开alt
            keybd_event((byte)Keys.Tab, 0, 2, UIntPtr.Zero);//松开tal
        }


    
    
    2、什么是extern?
        extern用于声明一个外部方法。它通常用于与非托管代码(如C/C++)进行交互,以便在C#中调用非托管代码中的函数。

        使用extern关键字可以将非托管函数的声明引入到C#代码中,以便在C#中调用该函数。声明外部函数时,需要使用DllImport特性来指定非托管库的名称和其他相关信息。
    
    
    3、Keys.Menu与Keys.Alt的区别?
        两者实则是一个键,在表示单一键时,用Keys.Menu;在表示组合(与Ctrl,Shift)时,用Keys.Alt,此时被视为修饰键。

    
    4、UIntPtr是什么?
        UIntPtr是一个结构体,用于表示一个指针或句柄的无符号整数。它可以用来表示指针或句柄的值,而无需关心具体的平台和指针的大小。UIntPtr的大小和指针的大小是平台相关的。在32位系统上,UIntPtr的大小为4字节,在64位系统上,UIntPtr的大小为8字节。

        在非托管的DLL中,当需要传递一个空指针或无效句柄时,可以使用UIntPtr.Zero来表示。UIntPtr.Zero是一个UIntPtr类型的静态字段,它的值为0,可以用于表示空指针或无效句柄。

        在非托管代码中,通常会使用整数类型(如int或IntPtr)来表示指针或句柄。当需要传递一个空指针或无效句柄时,可以将整数值设置为0。在C#中,可以使用UIntPtr.Zero来表示这个整数值为0的指针或句柄。


五、excel的dll引用


    非托管动态链接库是不能直接引用的,但为什么excel的dll是可以引用的?

    非托管动态链接库(DLL)是不能直接在C#代码中引用的。C#是一种托管语言,它运行在托管环境中,而非托管DLL是使用其他编程语言(如C++)编写的,并且运行在非托管环境中。要在C#代码中使用非托管DLL中的函数,需要使用DllImport特性和extern关键字来声明外部方法。

    然而,有一些特定的非托管DLL,如Excel的DLL(例如"Interop.Excel.dll"),它们是由Microsoft提供的专门用于与Excel进行交互的托管包装器。这些托管包装器DLL是使用C#或其他托管语言编写的,它们封装了与Excel交互所需的COM接口和功能,并提供了更方便的面向对象的API供C#开发人员使用。

    因此,当我们在C#项目中引用Excel的DLL时,实际上是引用了这些托管包装器DLL,而不是直接引用非托管DLL。这些托管包装器DLL已经处理了与非托管DLL的交互细节,并提供了更高级别的API,使我们可以更轻松地与Excel进行交互。

    总结,虽然非托管DLL一般需要通过P/Invoke机制来访问和调用,但某些特定的非托管DLL,如Excel的DLL,可以通过引用托管包装器DLL来提供更方便的API和交互方式。这样,我们可以直接在C#代码中使用这些托管包装器DLL提供的功能,而不需要手动进行P/Invoke调用。


    P/Invoke(Platform Invocation Services):
    是一种在.NET平台上调用非托管代码的技术。它允许.NET应用程序使用DllImport属性和相关的DllImport函数来调用C/C++等非托管代码中的函数。

    通过P/Invoke,可以在.NET应用程序中直接调用非托管动态链接库(DLL)中的函数。这对于需要访问操作系统API、硬件驱动程序或其他原生代码的情况非常有用。


 

更多推荐

基于Java+vue前后端分离学习交流论坛设计实现(源码+lw+部署文档+讲解等)

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

rv1126之isp黑电平(BLC)校准!

前言:大家好,今天我们继续来讲解isp第二期内容,这期内容主要分三个部分:1、tunning的工作流程2、利用RKISP2.x_Tuner来创建tunning工程,并连接上rv1126开发板进行抓图3、BLC(黑电平校准)的原理和校准方法以及实战那对于RKISP2.x_Tuner的工具使用,这个在第一期的内容里面有详细

从零开始在树莓派上搭建WordPress博客网站并实现公网访问

文章目录序幕概述1.安装PHP2.安装MySQL数据库3.安装Wordpress4.设置您的WordPress数据库设置MySQL/MariaDB创建WordPress数据库5.WordPressconfiguration6.将WordPress站点发布到公网安装相对URL插件修改config.php配置7.支持好友链

php程序设计的基本原则

单一职责原则(SRP):一个类应该只有一个原因引起变化,即一个类应该只负责一项职责。classUser{private$name;private$email;publicfunction__construct($name,$email){$this->name=$name;$this->email=$email;}pu

HTML5 游戏开发实战 | 俄罗斯方块

俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事。这款游戏看似简单但却变化无穷,游戏过程仅需要玩家将不断下落的各种形状的方块移动、翻转,如果某一行被方块充满了,那就将这一行消掉;而当窗口中无法再容纳下落的方块时,就宣告游戏结束。可见俄罗斯方块的需求如下。(

AI+游戏线下沙龙活动暨COC上海城市开发者社区8月活动

引言近年来,随着人工智能技术的不断发展和游戏开发技术的不断更新,越来越多的游戏公司开始将人工智能技术应用于游戏领域,以提高开发效率、降低成本,实现游戏玩家更好的游戏体验。为了探讨AI+游戏的技术实践经验,近日在亚马逊会议中心举办了一场以AI+游戏为主题的技术研讨会。在AI+游戏的技术实践研讨会上,与会者们分享了一些关于

云游戏下,会带来哪些技术变革

云游戏前言元宇宙是什么?云游戏的福利云游戏包括哪些技术前言大家好,在这里给大家介绍一个新名词----云游戏。可能有一些小伙伴了解过一些,也有一些小伙伴可能没有了解过,那这里就带大家了解一下元宇宙里的云游戏。2023年,如果说到什么最火🔥,什么最流行,那肯定是非元宇宙莫属了。自从2021年来,元宇宙就如同那雨后春笋一样

方案:数智化视频AI技术为智慧防汛筑基,构建防汛“数字堤坝”

一、背景分析在过去的几年中,全球气候变化导致许多城市在雨季面临严重的洪涝灾害。这些灾害不仅对人们的生命安全和财产造成威胁,也影响了城市的正常运转。传统的防汛手段主要依赖人力监控和应急指挥,但存在响应速度慢、处理效率低等问题。因此,我们需要一种智能、高效的解决方案来提高防汛效率和降低洪涝灾害的影响。随着新一代信息技术的普

【JavaSE专栏49】Java集合类LinkedList解析,链表和顺序表有什么不同?

作者主页:Designer小郑作者简介:3年JAVA全栈开发经验,专注JAVA技术、系统定制、远程指导,致力于企业数字化转型,CSDN学院、蓝桥云课认证讲师。主打方向:Vue、SpringBoot、微信小程序本文讲解了Java中集合类LinkedList的语法、使用说明和应用场景,并给出了样例代码。目录一、什么是Lin

[C++入门]---List的使用及模拟实现

文章目录1.list的介绍2.list的使用2.1list的构造函数2.2listmodifiers2.3listcapacity2.4listelmentaccess2.5iterator的使用3.list的模拟实现3.1list的源码1.list的介绍list是可以在常数范围内在任意位置进行插入和删除的序列式容器,

【Java 基础篇】深入理解Java HashMap:使用注意事项和性能优化

Java是一种广泛使用的编程语言,而集合是Java编程中不可或缺的一部分。在Java的集合框架中,HashMap是一个常用的数据结构,用于存储键值对。本文将深入介绍HashMap集合,从基础到高级用法,帮助您更好地理解和利用它。什么是HashMap?HashMap是Java集合框架中的一个类,它实现了Map接口,用于存

热文推荐