Marshal C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

using System.Runtime.InteropServices;

using System.Diagnostics;

 

namespace ConsoleApplication2

{

    public class CompactHeap<T> : IDisposable where T : new()

    {

        #region Fields

 

        private IntPtr _ptr, _currPtr;

        private int _rawSize;

        private Type _type;

        private T _t;

       

        #endregion

 

        public CompactHeap(int num)

        {

            _t = new T();

            _type = _t.GetType();

 

            _rawSize = Marshal.SizeOf(_t);

            _ptr = Marshal.AllocHGlobal(_rawSize * num);

            _currPtr = _ptr;

 

        }

 

        public void Add(T t)

        {

            Marshal.StructureToPtr(t, _ptr, false);

            _ptr = new IntPtr((_ptr.ToInt32() + _rawSize));

                  

        }

        public T Get(int index)

        {

            IntPtr p = new IntPtr(_currPtr.ToInt32() + _rawSize * index);

            return (T)Marshal.PtrToStructure(p, _type);

 

 

        }

 

        public void Dispose()

        {

            Marshal.FreeHGlobal(_currPtr);

        }

 

 

    }

    class Program

    {

        static void Main(string[] args)

        {

            int totalNum = 1000 * 10000;

 

            using (CompactHeap<Modes> head = new CompactHeap<Modes>(totalNum))

            {

                Stopwatch sw = new Stopwatch();

                sw.Start();

                for (int t = 0; t < totalNum; t++)

                {

                    Modes m = new Modes(); m.UserHeap = t; m.UserID = t; head.Add(m);

                   

                }

                sw.Stop();

                Console.WriteLine(sw.ElapsedMilliseconds.ToString());

 

 

                Modes m500000 = head.Get(500000);

                Console.WriteLine("m500000"+m500000.UserID);

 

                Modes m8 = head.Get(8);

                Console.WriteLine("m8"+m8.UserID);

 

 

               

 

            }

 

 

            Console.ReadLine();

        }

    }

    public struct Modes

    {

        public int UserID;

        public int UserHeap;

    }

 

   

}

 

 

//照到抄的,联想是,本来是因为在Vb 里面要传个VarPtr过去。不过弄到后面发现GC.Handle 的那个 IntPtr 好像不行吧。觉得这类型的应该是在Marshal 里面操作吧。毕竟这个是操作非托管堆的。So 真正要做的时候该杂做呢。Marshal.allochgolbal()建实例。不过感觉性能有限吧。但是觉得肯定可以传IntPtr.

posted on 2011-08-18 17:56  胖子黎  阅读(3629)  评论(0编辑  收藏  举报

导航