Posted on 2011-09-16
Medium Priority
Last Modified: 2012-06-27
I need to use Marshal.Copy function but I'm not sure about how to do that.
Now I try this :

Dim MyData(255) As Byte
..read data (MyData)  from ComPort

Marshal.Copy(BufferAddress, MyData, ind, 256)

Is it right or this can give some problems when ind will be too big?
How can i read ByteArray(255)  from data i have in Marshal?

Question by:mastiSoft
  • 4
  • 3
LVL 15

Expert Comment

ID: 36553179
You can allocate not managed memory using Marshal.AllocHGlobal.
This returns a IntPtr object (memory Pointer)

It is not safe use aritmetic with IntPtr.

You can Copy From and To your allocated memory using Marshall.Copy.
This allows copy from Managed memory to allocated an also from Allocated to managed.
Managed memory can be an Byte array and also any Blitable class or Structure.

Note that you need also Fee allocated memory (Marshall.FreeHGlobal).

You must take care about Memory Bounds as you can write on any memory with invalid length or invalid IntPtr.
This can cause unpredictable errors.


Author Comment

ID: 36553293
Your answer still doesn't open my mind. If I can't use arithmetic IntPtr how should I do .
The data flow in my computer and I have to save it somewhere to be able read back that amount of data I need . I can't believe that the only way to do that is create temporary binary file and manipulate data with FileGet,FilePut functions. if it so then VB net really big sh..  :-(((
LVL 15

Expert Comment

ID: 36553904
Note that IntPtr allows Convert to Int32 and Int64, you can add and substract offset, then create an new IntPtr from result.

But... Note that your program can run on 32 and 64 bits and conversions can become incorrect as correct IntPtr is unsigned integer and accepted conversion on .Net is from Signed integer.

Most times the original Intptr correspond to a Positive number and result from add an Offset is a Positive number, but you can´nt grants this is allways correct as a computer can manage 4gb memory and from 2gb limit correspond to negative numbers.

Note that Xp limit the memory from a Process to 2Gb, But this do´nt grants IntPtr is Positive number.

Note that Interop creates an releases not managed memory and you call not managed methods with interop.
Using Interop automatic mechanism, you avoid risks.

Here a sample where I allocate memory to do custom interop.
In this code, I Declare some vars as IntPtr on LzmaCompress and LzmaUncompress, then I need allocate memory and do Marsall.copy.

I can also declare it as Byte()  (Byte Array). Then Interop do all Work.
This opition is most Safe, But at this case, I manage a lot of memory (some Mb) and do´nt want allocate unnecesary managed memory and copy empty array (all zeros) to unmanaged memory ...

Declare Function LzmaCompress Lib "LZMA.dll" Alias "LzmaCompress" ( _
      ByVal dest As IntPtr, ByRef destLen As Int32, _
      ByVal src As IntPtr, ByVal srcLen As Int32, _
      ByVal outProps As IntPtr, ByRef outPropsSize As Int32, _
      ByVal level As Int32, _
      ByVal dictSize As Int32, ByVal lc As Int32, ByVal lp As Int32, _
      ByVal pb As Int32, ByVal fb As Int32, ByVal numThreads As Int32) As Int32

    Declare Function LzmaUncompress Lib "LZMA.dll" Alias "LzmaUncompress" ( _
       ByVal dest As IntPtr, ByRef destLen As Int32, _
       ByVal src As IntPtr, ByRef srcLen As Int32, _
       ByVal props As IntPtr, ByVal propsSize As Int32) As Int32

      Private Shared ReadOnly outProps As IntPtr = Marshal.AllocHGlobal(5)

      Public Function DeCode() As MemoryStream
          Dim Bytes() As Byte = Nothing
          If _CLength > 0 Then
             Dim il = Content.Length - 5, PtrIn = Marshal.AllocHGlobal(il)
             Marshal.Copy(Content, 0, outProps, 5)
             Marshal.Copy(Content, 5, PtrIn, il)

             Dim ol = _Length, out = Marshal.AllocHGlobal(ol)
             If LzmaUncompress(out, ol, PtrIn, il, outProps, 5) = 0 AndAlso ol = _Length Then
                  Bytes = New Byte(ol - 1) {}
                  Marshal.Copy(out, Bytes, 0, ol)
             End If
             If Bytes Is Nothing Then Throw New Exception("Error Descompresión")
             Bytes = Content
          End If
          Return New MemoryStream(Bytes) ', 0, Bytes.Length, True, True)
      End Function

      Public Sub EnCode(ByVal msIn As MemoryStream)
          _Length = CInt(msIn.Length)
          If _Length < 256 OrElse (Prj IsNot Nothing AndAlso Prj.Compress = False) Then
              Content = msIn.ToArray
              _CLength = 0
              Dim liBf = CInt(msIn.Length), iBf = Marshal.AllocHGlobal(liBf)
              Marshal.Copy(msIn.GetBuffer, 0, iBf, liBf)

              Dim lOBf = liBf - 5, OBf = Marshal.AllocHGlobal(lOBf)
              Dim loutProps = 5 'Valor máximo de OutPropos length

              Dim dsize = 1 << 19, mode = 5 'Tamaño diccionario, Modo - defecto=5, 4->Fast
              If liBf > dsize Then dsize = 1 << 20 : mode = 4
              Dim res = LzmaCompress(OBf, lOBf, iBf, liBf, outProps, loutProps, mode, dsize, -1, -1, -1, -1, -1)

              If res = 0 Then
                 Content = New Byte(lOBf + loutProps - 1) {}
                 Marshal.Copy(outProps, Content, 0, 5)
                 Marshal.Copy(OBf, Content, 5, lOBf)
                _CLength = Content.Length
                 Content = msIn.ToArray 'Tamaño comprimido sería mayor que original
                 _CLength = 0
              End If
          End If
          _Fecha = CType(Date.Now.Ticks \ TimeSpan.TicksPerMinute, Int32)
          Dirty = True
          version = PrjVers
          If Prj IsNot Nothing Then Prj.Dirty = True
      End Sub

Open in new window

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.


Author Comment

ID: 36554417
Thank you for answer. I try to understand  your code. You have 2 functions here and many undeclared variables. I can't see where you get data from memory (back after saving it in Marshal).
LVL 15

Expert Comment

ID: 36554672
Encode do a Lzma compress of Msin (memory Stream) and stores result on Content member.
Decode do a lzma decompress Content member and returns a memorystream.

I change  outProps  definition:

    Private Shared ReadOnly outProps(4) As Byte
     ByVal outProps As Byte(), ByRef outPropsSize As Int32, _
     ByVal props As Byte(), ByVal propsSize As Int32) As Int32
               Array.Copy(Content, outProps, 5)
               Array.Copy(outProps, Content, 5)

Now Interop allocates memory and release it for OutProps when I call LzmaCompress and LzmaUncompress.
Note that this var only has 5 bytes. Performance is not afected.

LVL 15

Accepted Solution

x77 earned 2000 total points
ID: 36554687
About Lzma compression:

Is a Opensource Project: http://sourceforge.net/projects/sevenzip/
There are a version that works as managed DLL (lzma#), but I use the c++ version.

Author Closing Comment

ID: 36554861
Thank you very much and have a nice weekend.

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
An ASP.NET Web Form User Control is not newly introduced in ASP.NET. In fact, it was an old technology yet still playing a role to generate web content, especially when we want to use it to have a better and easy way to control part of the web conte…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

589 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question