"Dynamic" data type is not of the same type as the native

1

I'm trying to create a struct that has one of its attributes having its dynamic or varied data type, I need (when running the struct constructor) to define its data type, and it should be the same as the native one because when I I'm trying to do this, but I'm not sure how to do this, but I'm not sure how to do this. thing "object {double}" instead of "double"

I need it to be native because I need to write an array of this struct into a hdf5 file, which can not write being a type that is not native

My struct:

struct opcSt
{
  public Int64 dt;
  public Int64 qlt;
  public dynamic vl;

  public opcSt(Int64 i, Int64 q, dynamic v)
  {
    dt = i;
    qlt = q;
    vl = v;        
  }

  public H5T.H5Type TypetoHDF5Type()
  {
    if (vl.GetType() == typeof(int))
    {
      return H5T.H5Type.NATIVE_INT;
    }
    if (vl.GetType() == typeof(Int64))
    {
      return H5T.H5Type.NATIVE_LONG;
    }
    if (vl.GetType() == typeof(float))
    {
      return H5T.H5Type.NATIVE_FLOAT;
    }
    if (vl.GetType() == typeof(double))
    {
      return H5T.H5Type.NATIVE_DOUBLE;
    }
    else { return H5T.H5Type.C_S1; }
  }
}

Here is the part where I instantiate in my code the struct that was created

foreach (Opc.Ua.DataValue dv in HistoryReadEnu(m_session, details, bvnodeId))
    {

      var aux = new opcSt((Int64)dv.SourceTimestamp.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds, dv.StatusCode.Code, dv.Value);

      arrayaux.Add(aux);
    }

I need a form that returns the raw type (native) double or whatever, float, int, whatever I spent in the constructor

Here is an image I got while debugging, which exemplifies exactly what I'm reporting

    
asked by anonymous 20.06.2018 / 20:46

1 answer

-1

I ended up generating some specific structs for each type of variable that I needed, because to generate the HDF5 file it was necessary to allocate a specific space for each type, so I chose to make a generic class (a helper) and from there instantiate the flow I needed based on the data type I read:

public class OpcToHdfHelper
  {
    public dynamic opcToRun;
    public void SetTypeAndWriteHdf(string bvtag, IOpcUaSession uaSession, Opc.Ua.ReadRawModifiedDetails readDetails,
                                   Opc.Ua.NodeId sourceId, H5GroupId group)
    {
       var data = HistoryReadEnu(uaSession, readDetails, sourceId);
      int i = 0;
      var p = data.ToArray()[i].Value;
      i = 1;
      while (p == null && i < 10)
  {

    p = data.ToArray()[i].Value;
    i++;
  } ;


  if (p.GetType() == typeof(int))
  {
    opcToRun = new OpcInt32(data, bvtag, group);
  }
  if (p.GetType() == typeof(Int64))
  {
    opcToRun = new OpcInt64();
  }
  if (p.GetType() == typeof(float))
  {
    opcToRun = new OpcFloat();
  }
  if (p.GetType() == typeof(double))
  {
    opcToRun = new OpcDouble(data, bvtag, group);
  }
  if(p.GetType() == typeof(string))
  {
    opcToRun = new OpcString(data, bvtag, group);
  }
  if(p.GetType() == typeof(bool))
  {
    opcToRun = new OpcBoolean(data, bvtag, group);
  }
}

Edit to clarify why different structs were needed:

  struct OpcString
  {
    public Int64 dt;
    public Int64 qlt;
    public IntPtr vl;

    public OpcString(Int64 timestamp = 0, Int64 quality = 0, string value="0")
    {
      dt = timestamp;
      qlt = quality;
      vl = new IntPtr();
      vl = ConvertTo(value);
    }

    IntPtr ConvertTo(string s)
    {
      var x = Marshal.StringToHGlobalAnsi(s);
      return x;
    }

    public OpcString(IEnumerable<Opc.Ua.DataValue> dados, string bvTag, H5GroupId groupId)
{
  dt = 0;
  qlt = 0;
  vl = new IntPtr();
  GenerateHdf5(dados, bvTag, groupId);
}
public void GenerateHdf5(IEnumerable<Opc.Ua.DataValue> dados, string bvTag, H5GroupId groupId)
{
  long[] dims = new long[1];
  dims[0] = dados.Count<Opc.Ua.DataValue>();
  H5DataSpaceId dataSpaceId = H5S.create_simple(1, dims);

  string auxLen = "";
  foreach(Opc.Ua.DataValue vc in dados)
  {
    if (vc.Value != null) { 
    if(vc.Value.ToString().Length > auxLen.Length)
    {
      auxLen = vc.Value.ToString();
    }
    }
  }



  H5DataTypeId stringTypeId = H5T.create(H5T.CreateClass.STRING, -1);


  OpcString opcHelper = new OpcString();

  H5DataTypeId dataTypeId = H5T.create(H5T.CreateClass.COMPOUND, Marshal.SizeOf(opcHelper));
  H5T.insert(dataTypeId, "Timestamp", 0, new H5DataTypeId(H5T.H5Type.NATIVE_LONG));
  H5T.insert(dataTypeId, "Quality", 8, new H5DataTypeId(H5T.H5Type.NATIVE_LONG));
  H5T.insert(dataTypeId, "Value", 16, stringTypeId);


  var list = new List<OpcString>();
  foreach (Opc.Ua.DataValue dv in dados)
  {
    string t = "NullValue";
    if(dv.Value != null)
    {
      t = dv.Value.ToString();
    }
    OpcString aux = new OpcString((Int64)dv.SourceTimestamp.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds, dv.StatusCode.Code, t);
    list.Add(aux);
  }
  H5DataSetId bvDset = H5D.create(groupId, bvTag, dataTypeId, dataSpaceId);
  H5D.write(bvDset, dataTypeId, new H5Array<OpcString>(list.ToArray()));

  H5D.close(bvDset);
  H5S.close(dataSpaceId);

    }
  }
  struct OpcBoolean



 {
    public Int64 dt;
    public Int64 qlt;
    public bool vl;

    public OpcBoolean(Int64 timestamp = 0, Int64 quality = 0, bool value = false)
    {
      dt = timestamp;
      qlt = quality;
      vl = value;
    }


    public OpcBoolean(IEnumerable<Opc.Ua.DataValue> dados, string bvTag, H5GroupId groupId)
    {
      dt = 0;
      qlt = 0;
      vl = false;
      GenerateHdf5(dados, bvTag, groupId);
    }
    public void GenerateHdf5(IEnumerable<Opc.Ua.DataValue> dados, string bvTag, H5GroupId groupId)
    {
  long[] dims = new long[1];
  dims[0] = dados.Count<Opc.Ua.DataValue>();
  H5DataSpaceId dataSpaceId = H5S.create_simple(1, dims);




  OpcBoolean opcHelper = new OpcBoolean();

  H5DataTypeId dataTypeId = H5T.create(H5T.CreateClass.COMPOUND, Marshal.SizeOf(opcHelper));
  H5T.insert(dataTypeId, "Timestamp", 0, new H5DataTypeId(H5T.H5Type.NATIVE_LONG));
  H5T.insert(dataTypeId, "Quality", 8, new H5DataTypeId(H5T.H5Type.NATIVE_LONG));
  H5T.insert(dataTypeId, "Value", 16, new H5DataTypeId(H5T.H5Type.NATIVE_HBOOL));



  var list = new List<OpcBoolean>();
  foreach (Opc.Ua.DataValue dv in dados)
  {
    OpcBoolean aux = new OpcBoolean((Int64)dv.SourceTimestamp.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds, dv.StatusCode.Code, Convert.ToBoolean(dv.Value));
    list.Add(aux);
  }
  H5DataSetId bvDset = H5D.create(groupId, bvTag, dataTypeId, dataSpaceId);
  H5D.write(bvDset, dataTypeId, new H5Array<OpcBoolean>(list.ToArray()));

  H5D.close(bvDset);
  H5S.close(dataSpaceId);

}
  }
    
22.06.2018 / 19:28