Hi Ray,
I found that you have posted a new post "covert between byte[] and int []"
for this issue.
I will follow up you there.
Thanks.
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! -
www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
--------------------
| From: "Ray Z" <
[email protected]>
| References: <#
[email protected]>
<#
[email protected]>
<
[email protected]>
<
[email protected]>
<
[email protected]>
| Subject: Re: Question about unsafe code
| Date: Mon, 3 Nov 2003 09:33:38 -0500
| Lines: 187
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.3790.0
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Message-ID: <
[email protected]>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: x42071bc2.ip.e-nt.net 66.7.27.194
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP12.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:196263
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Thanks, William
| So far, I get the idea that if I want to use bothe unmanaged and managed
| memory, I can not avoid memory copy. But I DO need to avoid it. I get a
idea
| that maybe I could use "union" to convert byte[] to int[] and so on. Here
is
| my source code, do you think this will work with GC?
|
| [StructLayout(LayoutKind.Explicit)]
|
| struct MyUnion
|
| {
|
| [FieldOffset(0)]
|
| public int[] i;
|
| [FieldOffset(0)]
|
| public byte[] b;
|
| }
|
| After I define this "union". I can use the following code to alloc and
| access the data buffer:
| MyUnion mu = new MyUnion();
| mu.a = new byte[640*480*4];
| //if I like access it as int[]
| int[] ip = mu.b;
|
| will this work?
|
|
|
| | > Here is a raw example with some ideas for you. If this does not help,
| > please explain in more detail what your after. Cheers!
| > --William Stacey, MVP
| >
| > private void button34_Click(object sender, System.EventArgs e)
| > {
| > int numInts = 5;
| > int numBytes = numInts * 4;
| > TestAlloc ta = new TestAlloc(numBytes);
| > byte[] ba = new byte[]{5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0};
| > ta.WriteSomeBytes(ba);
| > //Read 5 Ints
| > ta.ReadBytesAsInts(5);
| > ta.Close();
| > }
| >
| > public class TestAlloc
| > {
| > private int allocSize;
| > private readonly IntPtr allocPtr;
| > private int bytesToRead;
| >
| > public TestAlloc(int size)
| > {
| > if ( size < 4 )
| > throw new ArgumentOutOfRangeException("Must alloc multiple of 4
| bytes.");
| > if ( (size % 4) != 0 )
| > throw new ArgumentOutOfRangeException("Must alloc multiple of 4
| bytes.");
| > allocSize = size;
| > allocPtr = Marshal.AllocHGlobal(size);
| > }
| >
| > // Write some bytes to global memory.
| > public void WriteSomeBytes(byte[] ba)
| > {
| > if ( ba.Length > allocSize )
| > throw new ArgumentOutOfRangeException("Array too big.");
| > Marshal.Copy(ba, 0, allocPtr, ba.Length);
| > bytesToRead = ba.Length;
| > }
| >
| > // Read int[] from global memory.
| > public int[] ReadAsIntArray(int count)
| > {
| > if ( count < 1 )
| > throw new ArgumentException("count must be greater then one.");
| > if ( (count * 4) > bytesToRead )
| > throw new ArgumentException("count greater then number of integers
| > available.");
| > int[] ia = new int[count];
| > Marshal.Copy(allocPtr, ia, 0, count);
| > return ia;
| > }
| > //Read global bytes as ints without a copy.
| > public unsafe void ReadBytesAsInts(int count)
| > {
| > if ( count < 1 )
| > throw new ArgumentException("count must be greater then one.");
| > if ( (count * 4) > bytesToRead )
| > throw new ArgumentException("count greater then number of integers
| > available.");
| > int * pInt = (int *)allocPtr.ToPointer();
| > for (int i = 0; i < count; i++)
| > {
| > Console.WriteLine("Int{0} is:{1}", i, *pInt++);
| > }
| > }
| > public void Close()
| > {
| > Marshal.FreeHGlobal(allocPtr);
| > }
| > }
| >
| > --
| > William Stacey, MVP
| >
| > | > > Thanks, Eric
| > > Could you tell me is there any way to conver a byte[] to int []? Or,
in
| > > another approach, if I alloc a block of memory use Win32 API, could I
| > conver
| > > it to a byte[] without memory copy. I am working on image processing,
| copy
| > > memory again and again is unacceptable.
| > >
| > > | > > > I think you will have trouble with that approach.
| > > >
| > > > There is no way for you to persistantly fix/pin managed objects in
C#.
| > > Fixed
| > > > objects have a big impact on the GC, and keeping them around would
be
| > bad.
| > > >
| > > > If you really want to do this sort of thing, you should consider
doing
| > > your
| > > > own memory allocation by calling into the Win32 memory apis
yourself.
| > You
| > > > should be able to take in arrays of whatever type you want, lock
them,
| > and
| > > > then copy stuff around as you wish.
| > > >
| > > > --
| > > > Eric Gunnerson
| > > >
| > > > Visit the C# product team at
http://www.csharp.net
| > > > Eric's blog is at
http://blogs.gotdotnet.com/ericgu/
| > > >
| > > > This posting is provided "AS IS" with no warranties, and confers no
| > > rights.
| > > > | > > > > Thanks all.
| > > > > I think I did not make my question clear.
| > > > > I am going to write a MemoryPool which can manage a block memory
to
| > hold
| > > > > image data. I'd like seperate the whole block into a few small
| > > > pieces(double
| > > > > buffer). I will put lock in every pieces. I can not use the
Daniel's
| > > > > solution because the memory block is pretty big. I want to use
| IntPtr
| > > > > because I want to accept different type (byte, short and
int)memory
| > > > > referrence (or pointer). For examle, user already define a int []
| > Var1,
| > > > and
| > > > > read image data (32 bits color format) from a file. he can attach
| Var1
| > > to
| > > > > the pool. and, when he want to process the Red color data in the
| data,
| > > he
| > > > > can then get the byte[]Var2 (reference of same address of Var1)
from
| > the
| > > > > pool.. In c#, looks we can not directly conver a int[] to a
byte[].
| > And,
| > > > in
| > > > > some case, the pool need accept void*.
| > > > >
| > > > > Ray
| > > > >
| > > > >
| > > >
| > > >
| > >
| > >
| >
| >
|
|
|