kots's profile光荣与梦想——永远的CCCPPhotosBlogListsMore Tools Help

Blog


    May 23

    F1Book的WriteToBlob和ReadFromBlob

    简单说,F1Book的WriteToBlob和ReadFromBlob里的pBlob参数实际是内存块的handle.而且,WriteToBlob里的pBlob是out.反正我用了GlobalFree没什么问题。
     
        public class F1Tools
        {
            [DllImport("kernel32.dll")]
            private static extern IntPtr LocalAlloc(uint uFlags, UIntPtr uBytes);
            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern IntPtr LocalFree(IntPtr hMem);
            [DllImport("kernel32.dll")]
            private static extern uint LocalSize(IntPtr hMem);
            [DllImport("kernel32.dll")]
            private static extern IntPtr LocalLock(IntPtr hMem);
            [DllImport("kernel32.dll")]
            private static extern bool LocalUnlock(IntPtr hMem);
            [DllImport("kernel32.dll")]
            private static extern IntPtr GlobalFree(IntPtr hMem);
            [DllImport("coredll.dll", SetLastError = true)]
            private static extern Int32 GetLastError();
            [DllImport("kernel32.dll")]
            private static extern UIntPtr GlobalSize(IntPtr hMem);
            [DllImport("kernel32.dll")]
            private static extern IntPtr GlobalLock(IntPtr hMem);
            [DllImport("kernel32.dll")]
            private static extern bool GlobalUnlock(IntPtr hMem);
            [DllImport("kernel32.dll")]
            static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes);
            /// <summary>
            /// 将F1Book的内容放入缓冲区
            /// </summary>
            /// <param name="book"></param>
            /// <param name="content"></param>
            /// <returns></returns>
            public static bool GetContentFromF1Book(F1BookView book, out byte[] content)
            {
                bool ret = false;
                content = null;
                try
                {
                    int pblob;
                    book.WriteToBlob(out pblob, 0);//取得句柄
                    if (pblob != 0)
                    {
                        //句柄有效
                        IntPtr hmem = new IntPtr(pblob);
                        if (hmem != IntPtr.Zero)
                        {
                            try
                            {
                                int len = (int)GlobalSize(hmem).ToUInt32();//取得内存块长度
                                IntPtr mptr = GlobalLock(hmem);//取得内存块地址
                                if (mptr != IntPtr.Zero)
                                {
                                    //地址有效
                                    try
                                    {
                                        content = new byte[len];
                                        Marshal.Copy(mptr, content, 0, len);//复制数据
                                        ret = true;
                                    }
                                    finally
                                    {
                                        GlobalUnlock(hmem);//确保unlock
                                    }
                                }
                            }
                            finally
                            {
                                GlobalFree(hmem);//确保释放内存
                            }
                        }
                    }
                }
                catch
                { }
                return ret;
            }
            /// <summary>
            /// 将缓冲区的内容放入F1Book
            /// </summary>
            /// <param name="book"></param>
            /// <param name="content"></param>
            public static void PutContentToF1Book(F1BookView book, byte[] content)
            {
                if ((book != null) && (content != null))
                {
                    //确认参数非空
                    //分配内存
                    IntPtr hmem = GlobalAlloc((int)GlobalMemoryFlags.GMEM_MOVEABLE, new UIntPtr((uint)content.Length));
                    if (hmem != IntPtr.Zero)
                    {
                        //有效句柄
                        try
                        {
                            IntPtr pmem = GlobalLock(hmem);
                            try
                            {
                                Marshal.Copy(content, 0, pmem, content.Length);
                            }
                            finally
                            {
                                GlobalUnlock(hmem);
                            }
                            book.ReadFromBlob(hmem.ToInt32(), 0);
                        }
                        finally
                        {
                            GlobalFree(hmem);
                        }
                    }
                }
            }
        }