Solved

Marshal.Copy

Posted on 2011-09-16
7
706 Views
Last Modified: 2012-06-27
Hi,
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
Do
..read data (MyData)  from ComPort

Marshal.Copy(BufferAddress, MyData, ind, 256)
ind=ind+256
Loop

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?




0
Comment
Question by:mastiSoft
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 15

Expert Comment

by:x77
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.

http://msdn.microsoft.com/en-us/library/ms146625.aspx
0
 
LVL 1

Author Comment

by:mastiSoft
ID: 36553293
Hi,
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..  :-(((
0
 
LVL 15

Expert Comment

by:x77
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
             Marshal.FreeHGlobal(PtrIn)
             Marshal.FreeHGlobal(out)
             If Bytes Is Nothing Then Throw New Exception("Error Descompresión")
          Else
             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
          Else
              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
              Else
                 Content = msIn.ToArray 'Tamaño comprimido sería mayor que original
                 _CLength = 0
              End If
              Marshal.FreeHGlobal(iBf)
              Marshal.FreeHGlobal(OBf)
          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

0
Guide to Performance: Optimization & Monitoring

Nowadays, monitoring is a mixture of tools, systems, and codes—making it a very complex process. And with this complexity, comes variables for failure. Get DZone’s new Guide to Performance to learn how to proactively find these variables and solve them before a disruption occurs.

 
LVL 1

Author Comment

by:mastiSoft
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).
0
 
LVL 15

Expert Comment

by:x77
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.

0
 
LVL 15

Accepted Solution

by:
x77 earned 500 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.
http://www.7-zip.org/sdk.html
0
 
LVL 1

Author Closing Comment

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

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Sometimes a user will call me frantically, explaining that something has gone wrong and they have tried everything (read - they have messed it up more and now need someone to clean up) and it still does no good, can I help them?!  Usually the standa…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
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.

751 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