整理c#托管资源和非托管资源区别

本文详细阐述了托管与非托管资源的概念,介绍了在.NET框架下如何管理内存资源,包括托管资源的自动回收机制和非托管资源的手动管理方式。同时提供了一个调用非托管API方法的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

托管的概念是在.net框架诞生后出现的。用比较通俗的话解释就是运行在.net框架下,并受.net框架管理的应用或其他组件称为托管的,反之为非托管的。也就是说用.net平台开发出来的程序应该就是托管的了,而在.net以前开发的程序都属于非托管的。但是非托管的程序完全可以通过在.net平台下重新生成而变成托管的 ,你就把.net framework理解为一个Microsoft的Java Virtual Machine,这样,东西在上面跑,完全受控,这就是managed code。

==================================

所谓非托管资源是你通过P/Invoke之类方法得到的os资源,CLR没有办法帮你释放这些资源。如果你对这些资源提供了包装WrapSource。那么这个WrapSource是托管资源了.他可能管理了非托管资源。但他自己是托管的。

==================================

托管和非托管是修饰内存的:
托管的意思,你不用直接操作内存,你需要的时候跟我说。我替你申请,然后给你用,你用完可以告诉我,我帮你释放,如果你忙,忘记告诉我了,我也会在定期去帮你释放的。 这就是托管,你打交道的不是直接的内存,而是.net clr。
非托管的意思就是你要自己负责管理内存,这里所说的内存管理。实际上只是堆上的内存管理,栈内存和以前的一样,函数退出则释放,heap上的内存,非托管内存需要自己分配,调用构造函数(c需要,c++里用new替代这部操作了),使用完毕后,需要自己释放这个内存,如果你不小心,把
指向内存的指针弄丢了,就造成内存泄露了,这个内存泄露在你程序退出之前是无法弥补的,所以要小心。(virtualMalloc的情况不在此描述了。因为分配的也不是heap上的内存,属于扩展内存空间,题外话了。)

实例:调用kernel32.dll中的非托管方法"GetSystemTime"将系统时间返回给定制的类MySystemTime并执行输出.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace DllImportTest
{
    /// <summary>
    /// 定义一个用于接收非托管API方法返回值的类
    /// StructLayout定义了该类的各个成员在物理上的排列方式
    /// </summary>
    [StructLayout(LayoutKind.Explicit, Size = 16, CharSet = CharSet.Ansi)]
    public class MySystemTime
    {
        [FieldOffset(0)]
        public ushort wYear;
        [FieldOffset(2)]
        public ushort wMonth;
        [FieldOffset(4)]
        public ushort wDayOfWeek;
        [FieldOffset(6)]
        public ushort wDay;
        [FieldOffset(8)]
        public ushort wHour;
        [FieldOffset(10)]
        public ushort wMinute;
        [FieldOffset(12)]
        public ushort wSecond;
        [FieldOffset(14)]
        public ushort wMilliseconds;
    }
    /// <summary>
    /// 用LibWrapper的静态方法来调用非托管API方法"GetSystemTime"
    /// </summary>
    class LibWrapper
    {
        [DllImport("kernel32.dll", EntryPoint = "GetSystemTime")]
        //如果定义的方法名称与要进行封装的非托管API方法不同则需要在DLLImport中指定入口点.
        public static extern void gettime([MarshalAs(UnmanagedType.LPStruct)]MySystemTime st);
    }

    class TestApplication
    {
        public static void Main()
        {
            try
            {
                MySystemTime sysTime = new MySystemTime();
                //LibWrapper.GetSystemTime(sysTime);
                LibWrapper.gettime(sysTime);
                Console.WriteLine("The System time is {0}/{1}/{2} {3}:{4}:{5}", sysTime.wDay,
                   sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
            }
            catch (TypeLoadException e)
            {
                Console.WriteLine("TypeLoadException : " + e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception : " + e.Message);
            }
        }
    }

}


参考:http://www.cnblogs.com/xianspace/archive/2009/04/08/1431723.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值