认识非托管动态链接库

一、非托管动态链接库

    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、硬件驱动程序或其他原生代码的情况非常有用。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值