Search code examples
c#pinvokehdf5

Only first character being written to HDF5 string attribute


Just started learning HDF5 and found a string attribute in an existing HDF5 file that I'm trying to emulate. When I execute this C# code (using HDF5 PInvoke ver 1.10.1):

long typeId = H5T.copy(H5T.C_S1);
H5T.set_cset(typeId, H5T.cset_t.UTF8);
H5T.set_size(typeId, new IntPtr(3));
long spaceId = H5S.create(H5S.class_t.SCALAR);
long attributeId = H5A.create(dataSetId, "StringAttribute", typeId, spaceId);
char[] data = "abc".ToCharArray();
IntPtr dataBuffer = Marshal.AllocHGlobal(data.Length * sizeof(char));
Marshal.Copy(data, 0, dataBuffer, data.Length);
H5A.write(attributeId, typeId, dataBuffer);

HDFView 3.0 shows Name="StringAttribute", Value="a", Type="String,length=3", ArraySize="Scalar". Why doesn't Value="abc"?

Edit: David Heffernan's comment made me realize I was being lazy in my copy/paste and missed the required conversion from Unicode to 8-bit, accomplished with this code

byte[] data = Encoding.UTF8.GetBytes("abc");
IntPtr dataBuffer = Marshal.AllocHGlobal(data.Length);

Solution

  • You are supplying UTF16 encoded text but the library expects 8 bit text. I don't know the library but I expect it requires UTF8 encoded text.

    Use Encoding.UTF8.GetBytes to obtain the UTF8 encoded text. Or if ASCII is expected then Encoding.ASCII.GetBytes.