Jesse, how are you? Please have a look at the attached IronPython script.
It shows how to write a compound type with two integer members and one
variable-length string member. I'm sure there are more elegant ways, but the
brute force writing of a byte array is effective. We use
BitConverter to get the bytes from the integers and the pointer (converted
to an
integer of the right size). Use Marshal.StringToHGlobalAnsi to obtain a
pointer to a good old-fashioned string on the global heap.
(Free later with Marshal.FreeHGlobal.)
Best, G.
-----Original Message-----
From: [email protected] [mailto:[email protected]]
On Behalf Of Jesse Lai
Sent: Monday, January 23, 2012 1:21 PM
To: HDF Users Discussion List
Subject: [Hdf-forum] HDF5.net Compound datatype with variable length string
Hello All,
I'm trying to write some attributes to a dataset and I'd like to use a
compound data type to hold the information. I'm using C# and the .NET
wrapper. I can read/write just regular string and variable length string
datasets and/or attributes with the wrapper, but I can't figure out a good
way to write with a compound datatype with a variable length string.
I've tried the following:
1) Create a struct with the SequentialLayout attribute. Then, I created a
field for each member of the datatype. For the variable length types, I use
the IntPtr. In the constructor for the struct, I generate the pointer to
the string value.
2) I create a HDF5 compound datatype. I insert fields and for the string
types, I use a type derived from C_S1 and set it to variable length. I use
an offset of 4 for the length.
3) Then I created a dataset of the new datatype.
4) Next, I create a C# array of the struct values.
5) Finally, I tried writing the array of structs to the dataset.
However, in that last statement I am getting an exception. Is there a
transformation of the struct that I need to do before writing the array? I
can post the full code that I've tried if that is helpful in diagnosing.
Thanks,
Jesse
_______________________________________________
Hdf-forum is for HDF software users discussion.
[email protected]
http://mail.hdfgroup.org/mailman/listinfo/hdf-forum_hdfgroup.org
import clr
clr.AddReferenceToFile('HDF5DotNet.dll')
import HDF5DotNet
from HDF5DotNet import *
#===============================================================================
import System
from System import Array, BitConverter, Byte, Int32, Int64, IntPtr, String
import System.Runtime.InteropServices
from System.Runtime.InteropServices import Marshal
#===============================================================================
print '\nInitializing HDF5 library\n'
status = H5.Open()
npoints = 3
shape = Array[Int64]((npoints, ))
strings = Array.CreateInstance(String, shape)
strings[0] = "Wake Me up When"
strings[1] = "September"
strings[2] = "Ends"
pointers = Array.CreateInstance(IntPtr, shape)
pointers[0] = Marshal.StringToHGlobalAnsi(strings[0])
pointers[1] = Marshal.StringToHGlobalAnsi(strings[1])
pointers[2] = Marshal.StringToHGlobalAnsi(strings[2])
h5file = H5F.create('cmpvs.h5', H5F.CreateMode.ACC_TRUNC)
stype = H5T.create(H5T.CreateClass.STRING, -1)
ctype = H5T.create(H5T.CreateClass.COMPOUND, 8+IntPtr.Size)
H5T.insert(ctype, "var1", 0, H5DataTypeId(H5T.H5Type.NATIVE_INT))
H5T.insert(ctype, "var2", 4, stype)
H5T.insert(ctype, "var3", 4+IntPtr.Size, H5DataTypeId(H5T.H5Type.NATIVE_INT))
sizeof = 8+IntPtr.Size
shape = Array[Int64]((npoints, ))
dspace = H5S.create_simple(shape.Length, shape)
dset = H5D.create(h5file, 'Sample', ctype, dspace)
shape = Array[Int64]((npoints*sizeof, ))
data = Array.CreateInstance(Byte, shape)
offset = 0
for i in range(npoints):
offset = i*sizeof
a = Int32(i)
Array.Copy(BitConverter.GetBytes(a), 0, data, offset, 4)
if IntPtr.Size == 8: b = pointers[i].ToInt64()
else: b = pointers[i].ToInt32()
Array.Copy(BitConverter.GetBytes(b), 0, data, offset+4, IntPtr.Size)
c = Int32(i*i)
Array.Copy(BitConverter.GetBytes(c), 0, data, offset+4+IntPtr.Size, 4)
status = H5D.write(dset, ctype, H5Array[Byte](data))
H5D.close(dset)
H5S.close(dspace)
H5T.close(ctype)
H5T.close(stype)
H5F.close(h5file)
Marshal.FreeHGlobal(pointers[0])
Marshal.FreeHGlobal(pointers[1])
Marshal.FreeHGlobal(pointers[2])
print '\nShutting down HDF5 library\n'
status = H5.Close()
_______________________________________________
Hdf-forum is for HDF software users discussion.
[email protected]
http://mail.hdfgroup.org/mailman/listinfo/hdf-forum_hdfgroup.org