Solved

Marshal.Copy

Posted on 2011-09-16
7
674 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
  • 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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
crm development 2 39
.net VBA word safemode 1 25
VB.NET HttpWebRequest 12 34
Open a word document 23 19
In a recent article here at Experts Exchange (http://www.experts-exchange.com/articles/18880/PaperPort-14-in-Windows-10-A-First-Look.html), I discussed my nine-month sandbox testing of the Windows 10 Technical Preview, specifically with respect to r…
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 video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

744 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now