473,396 Members | 1,963 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Marshal large byte array into array of structs?

I have a piece of code that needs to read the contents of a binary file
(that I've created with another app) into an array of structures. The
binary data in the file represents just a series of singles that
correspond to those in my structure detailed below. So when I load the
file, all that I know for certain is that there will be some multiple
of these eight singles represented in the binary data.
My code below will read the data correctly, but only marshals one
structure (8 singles) at a time, forcing me to loop through the binary
array in chunks. With the large amount of data I need to read, this is
very slow.

In C++, I can load data from the same file into an array of these
structures with a single call to fread() and it's very fast. Can anyone
give me a tip on how to accomplish this in .NET?

Thanks in advance.
Code that loads one struct at a time:

<StructLayout(LayoutKind.Sequential)> Public Structure MyStruct
<MarshalAs(UnmanagedType.R4)> Dim X As Single
<MarshalAs(UnmanagedType.R4)> Dim Y As Single
<MarshalAs(UnmanagedType.R4)> Dim Z As Single
<MarshalAs(UnmanagedType.R4)> Dim tu As Single
<MarshalAs(UnmanagedType.R4)> Dim tv As Single
<MarshalAs(UnmanagedType.R4)> Dim NX As Single
<MarshalAs(UnmanagedType.R4)> Dim NY As Single
<MarshalAs(UnmanagedType.R4)> Dim NZ As Single
End Structure

Public Sub ReadBinaryIntoStructArray(ByVal FileName As String,
ByRef ArrayOfStructs() As MyStruct)
Dim bFileOpen As Boolean = False
Dim bHeapAlloc As Boolean = False
Dim fstm As FileStream
Dim binaryData() As Byte
Dim bytesRead As Long
Dim iStructSize As Int32
Dim iCurVertNum As Int32
Dim ptrTarget As IntPtr
Dim oSingleStruct As Object
Try
fstm = New FileStream(FileName, FileMode.Open,
FileAccess.Read, FileShare.Read)
bFileOpen = True
binaryData = New Byte(fstm.Length - 1) {}
bytesRead = fstm.Read(binaryData, 0, CInt(fstm.Length))
iStructSize = Marshal.SizeOf(GetType(MyStruct))
ArrayOfStructs = New MyStruct(CInt(fstm.Length /
iStructSize) - 1) {}
'Until I can find a better bulk-copy method, we must load
one vert (8 singles) at a time).
iCurVertNum = 0
ptrTarget = Marshal.AllocHGlobal(iStructSize)
bHeapAlloc = True
For iCurVertNum = 0 To ArrayOfStructs.Length - 1

Marshal.Copy(binaryData, iCurVertNum * iStructSize,
ptrTarget, iStructSize)
oSingleStruct = Marshal.PtrToStructure(ptrTarget,
GetType(MyStruct))

ArrayOfStructs(iCurVertNum).X = oSingleStruct.X
ArrayOfStructs(iCurVertNum).Y = oSingleStruct.Y
ArrayOfStructs(iCurVertNum).Z = oSingleStruct.Z
ArrayOfStructs(iCurVertNum).tu = oSingleStruct.tu
ArrayOfStructs(iCurVertNum).tv = oSingleStruct.tv
ArrayOfStructs(iCurVertNum).NX = oSingleStruct.NX
ArrayOfStructs(iCurVertNum).NY = oSingleStruct.NY
ArrayOfStructs(iCurVertNum).NZ = oSingleStruct.NZ
Next
Marshal.FreeHGlobal(ptrTarget)
bHeapAlloc = False
Catch ex As System.OutOfMemoryException
Throw ex
Catch e As Exception
Throw e
Finally
If bFileOpen Then
fstm.Close()
End If
fstm = Nothing
If bHeapAlloc Then
Marshal.FreeHGlobal(ptrTarget)
End If
End Try
End Sub

Nov 21 '05 #1
2 4824
Does anyone at least know whether or not this is going to be possible
in VB.NET?

Thanks again.

Nov 21 '05 #2
Ok, now realizing that this thread would prob be more appropriate for
the Interop group, I've come up with a solution that seems to work fine
and loads/copies a couple of hundred thousand structures into the array
about as fast as my C++ version (well under a second).

Here's the bulk solution, which (typically) ended up being much
shorter/easier once I got on the right track.

Public Sub ReadBinaryTerrainData(ByVal FileName As String, ByRef
ArrayOfStructs() As MyStruct)
Dim bFileOpen As Boolean = False
Dim fstm As FileStream
Dim binaryData() As Byte
Dim bytesRead As Long
Dim iStructSize As Int32
Dim prtMyStruct As IntPtr
Dim gch As GCHandle
Try
'Open the file and read the binary data into a byte array.
fstm = New FileStream(FileName, FileMode.Open,
FileAccess.Read, FileShare.Read)
bFileOpen = True
binaryData = New Byte(fstm.Length - 1) {}
bytesRead = fstm.Read(binaryData, 0, CInt(fstm.Length))
'Initialize/size our array of vertices.
iStructSize = Marshal.SizeOf(GetType(MyStruct))
ArrayOfStructs =
System.Array.CreateInstance(GetType(MyStruct), CInt(fstm.Length /
iStructSize))
'Get a handle to the vert array, pinning it to keep GC from
'zeroing it or moving it around.
gch = GCHandle.Alloc(ArrayOfStructs, GCHandleType.Pinned)
'Get a pointer to the vert array.
prtMyStruct = gch.AddrOfPinnedObject()
'Use that pointer as a destination to which to copy the
binary data
'from the byte array.
Marshal.Copy(binaryData, 0, prtMyStruct, bytesRead)
'Free the pinned handle so GC can do it's thing from here
on.
gch.Free()
Catch ex As System.OutOfMemoryException
' An exception could occur if the system is out of
' memory and the block of heap memory could not be
' set aside for you.
Throw ex
Catch e As Exception
' General exception caught, show the message and move on...
Throw e
Finally
If bFileOpen Then
fstm.Close()
End If
fstm = Nothing
If gch.IsAllocated() Then
gch.Free()
End If
End Try
End Sub

Nov 21 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Eric Hendriks | last post by:
// In an unmanaged DLL the following function must be called: // int VFGeneralize(const BYTE * const * features); // "features" parameter is supposed to be an array of byte arrays. // function is...
0
by: William Stacey | last post by:
The following code works, but I can't figure out why. I take a struct with two members, a single byte and byte. I then marshal the whole struct to a byte. I create a new struct (without init'ing...
9
by: Angel | last post by:
Hi again, I'm trying to call functions from a proprietary DLL but it's turned out to be more difficult than I thought. I have this W32.DLL which was written in C by USPS. They don't provide the...
6
by: SB | last post by:
I feel dumb to ask because I bet this is a simple question... Looking at the code below, can someone please explain why I get two different values in my Marshal.SizeOf calls (see the commented...
1
by: dhornyak | last post by:
I have been banging my head against the wall for a while now, and can't seem to id the problem. I've been through a ton of posts and the code doesn't seem any different. Can anybody see it? When...
10
by: David Fort | last post by:
Hi, I'm upgrading a VB6 app to VB.net and I'm having a problem with a call to a function provided in a DLL. The function takes the address of a structure which it will fill in with values. I...
2
by: O.B. | last post by:
I have a structure named EntityState with an explicit layout. The following two operations exist within the class to return a byte array representing the current object. Upon executing them each a...
2
by: O.B. | last post by:
When using Marshal to copy data from a byte array to the structure below, only the first byte of the "other" array is getting copied from the original byte array. What do I need to specify to get...
2
by: O.B. | last post by:
I have operation within a class that marshals the data into a byte array. Below are three different ways that work. Are there any downsides to using one over the the other? public virtual byte...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.