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

Reply via email to