Nontrivial structure?

  • Thread starter Christian Kaiser
  • Start date
C

Christian Kaiser

Good evening (here in Germany at least),

I have a structure, expressed in C++ as:

clsByte2 m_Sensor[6];
clsByte1 m_Output[1];
clsByte1 m_PowerReduction[1];
clsByte1 m_AnalogOutput[1];
clsByte1 m_EnergyEntries[1];
clsPowerAndEnergyDataUVR61 m_Energy[1];
clsByte2 m_Unknown2[1];
clsDateTime m_DateTime;
clsByte3 m_TimeSinceStartOfStoring;


where clsByte1, clsByte2, clsDateTime, ... are classes, having members as
needed (clsByte1 is a one-byte class wth accessor functions for this byte,
clsByte2 etc likewise, see appended code). The arrays with [1] are defined
that way as I have multiple structures with different counts of these
values, but I can live without the '[1]' if needed.

How can I define such a nontrivial structure using c#?

This structure needs to be fixed byte-packed as I read it from the COM
port - it's a binary structure of a photothermic control.



I tried:

[StructLayout(LayoutKind.Explicit, Size=35)]
struct scData
{
[FieldOffset(0)] public fixed clsByte2 m_Sensor[6];
[FieldOffset(12)] public fixed clsByte1 m_Output[1];
[FieldOffset(13)] public fixed clsByte1 m_PowerReduction[1];
[FieldOffset(14)] public fixed clsByte1 m_AnalogOutput[1];
[FieldOffset(15)] public fixed clsByte1 m_EnergyEntries[1];
[FieldOffset(16)] public fixed clsPowerAndEnergyDataUVR61 m_Energy[1];
[FieldOffset(24)] public fixed clsByte2 m_Unknown2[1];
[FieldOffset(26)] public clsDateTime m_DateTime;
[FieldOffset(32)] public clsByte3 m_TimeSinceStartOfStoring;
}


after haveing defined all the member structs, but C# now complains "Error 1
Fixed size buffer type must be one of the following: bool, byte, short, int,
long, char, sbyte, ushort, uint, ulong, float or double C:\Documents and
Settings\combit\my documents\visual studio
2005\Projects\WindowsApplication1\WindowsApplication1\DeviceTA.cs"

Is there any method I can define such a structure in C# at all? Is C#
unusable for these designs?



Thanks,



Christian

---------



class clsByte2
{
private:
BYTE _nData[2];
public:
clsByte2(void)
{
_nData[0] = 0;
_nData[1] = 0;
}
clsByte2(const clsByte2& rhs)
{
_nData[0] = rhs._nData[0];
_nData[1] = rhs._nData[1];
}
clsByte2(int nValue)
{
_nData[0] = (BYTE)(nValue & 0xff);
_nData[1] = (BYTE)((nValue >> 8) & 0xff);
}
clsByte2& operator=(const clsByte2& rhs)
{
if (&rhs != this)
{
_nData[0] = rhs._nData[0];
_nData[1] = rhs._nData[1];
}
return(*this);
}

int AsInt(void) const
{
if (_nData[0] == -1 &&
_nData[1] == -1)
return(-1);
return(_nData[0] + 256 * _nData[1]);
}
int operator[](int n) const
{
return(_nData[n]);
}
};
 
C

Cordell Lawrence

Christian, while I have no idea doing this using the attributes that you've
used, have you considered adding a method to the struct that allows you to
serialize this struct to a byte stream and deserialize one from a byte
stream or is that too much trouble?

Hope this helps,
Cordell Lawrence
Teleios Systems

Christian Kaiser said:
Good evening (here in Germany at least),

I have a structure, expressed in C++ as:

clsByte2 m_Sensor[6];
clsByte1 m_Output[1];
clsByte1 m_PowerReduction[1];
clsByte1 m_AnalogOutput[1];
clsByte1 m_EnergyEntries[1];
clsPowerAndEnergyDataUVR61 m_Energy[1];
clsByte2 m_Unknown2[1];
clsDateTime m_DateTime;
clsByte3 m_TimeSinceStartOfStoring;


where clsByte1, clsByte2, clsDateTime, ... are classes, having members as
needed (clsByte1 is a one-byte class wth accessor functions for this byte,
clsByte2 etc likewise, see appended code). The arrays with [1] are defined
that way as I have multiple structures with different counts of these
values, but I can live without the '[1]' if needed.

How can I define such a nontrivial structure using c#?

This structure needs to be fixed byte-packed as I read it from the COM
port - it's a binary structure of a photothermic control.



I tried:

[StructLayout(LayoutKind.Explicit, Size=35)]
struct scData
{
[FieldOffset(0)] public fixed clsByte2 m_Sensor[6];
[FieldOffset(12)] public fixed clsByte1 m_Output[1];
[FieldOffset(13)] public fixed clsByte1 m_PowerReduction[1];
[FieldOffset(14)] public fixed clsByte1 m_AnalogOutput[1];
[FieldOffset(15)] public fixed clsByte1 m_EnergyEntries[1];
[FieldOffset(16)] public fixed clsPowerAndEnergyDataUVR61 m_Energy[1];
[FieldOffset(24)] public fixed clsByte2 m_Unknown2[1];
[FieldOffset(26)] public clsDateTime m_DateTime;
[FieldOffset(32)] public clsByte3 m_TimeSinceStartOfStoring;
}


after haveing defined all the member structs, but C# now complains "Error 1
Fixed size buffer type must be one of the following: bool, byte, short, int,
long, char, sbyte, ushort, uint, ulong, float or double C:\Documents and
Settings\combit\my documents\visual studio
2005\Projects\WindowsApplication1\WindowsApplication1\DeviceTA.cs"

Is there any method I can define such a structure in C# at all? Is C#
unusable for these designs?



Thanks,



Christian

---------



class clsByte2
{
private:
BYTE _nData[2];
public:
clsByte2(void)
{
_nData[0] = 0;
_nData[1] = 0;
}
clsByte2(const clsByte2& rhs)
{
_nData[0] = rhs._nData[0];
_nData[1] = rhs._nData[1];
}
clsByte2(int nValue)
{
_nData[0] = (BYTE)(nValue & 0xff);
_nData[1] = (BYTE)((nValue >> 8) & 0xff);
}
clsByte2& operator=(const clsByte2& rhs)
{
if (&rhs != this)
{
_nData[0] = rhs._nData[0];
_nData[1] = rhs._nData[1];
}
return(*this);
}

int AsInt(void) const
{
if (_nData[0] == -1 &&
_nData[1] == -1)
return(-1);
return(_nData[0] + 256 * _nData[1]);
}
int operator[](int n) const
{
return(_nData[n]);
}
};
 
S

Sergei

Christian Kaiser said:
Good evening (here in Germany at least),

I have a structure, expressed in C++ as:

clsByte2 m_Sensor[6];
clsByte1 m_Output[1];
clsByte1 m_PowerReduction[1];
clsByte1 m_AnalogOutput[1];
clsByte1 m_EnergyEntries[1];
clsPowerAndEnergyDataUVR61 m_Energy[1];
clsByte2 m_Unknown2[1];
clsDateTime m_DateTime;
clsByte3 m_TimeSinceStartOfStoring;


where clsByte1, clsByte2, clsDateTime, ... are classes, having members as
needed (clsByte1 is a one-byte class wth accessor functions for this byte,
clsByte2 etc likewise, see appended code). The arrays with [1] are defined
that way as I have multiple structures with different counts of these
values, but I can live without the '[1]' if needed.

How can I define such a nontrivial structure using c#?

This structure needs to be fixed byte-packed as I read it from the COM
port - it's a binary structure of a photothermic control.



I tried:

[StructLayout(LayoutKind.Explicit, Size=35)]
struct scData
{
[FieldOffset(0)] public fixed clsByte2 m_Sensor[6];
[FieldOffset(12)] public fixed clsByte1 m_Output[1];
[FieldOffset(13)] public fixed clsByte1 m_PowerReduction[1];
[FieldOffset(14)] public fixed clsByte1 m_AnalogOutput[1];
[FieldOffset(15)] public fixed clsByte1 m_EnergyEntries[1];
[FieldOffset(16)] public fixed clsPowerAndEnergyDataUVR61 m_Energy[1];
[FieldOffset(24)] public fixed clsByte2 m_Unknown2[1];
[FieldOffset(26)] public clsDateTime m_DateTime;
[FieldOffset(32)] public clsByte3 m_TimeSinceStartOfStoring;
}


after haveing defined all the member structs, but C# now complains "Error 1
Fixed size buffer type must be one of the following: bool, byte, short, int,
long, char, sbyte, ushort, uint, ulong, float or double C:\Documents and
Settings\combit\my documents\visual studio
2005\Projects\WindowsApplication1\WindowsApplication1\DeviceTA.cs"

Is there any method I can define such a structure in C# at all? Is C#
unusable for these designs?

An array is a reference type in C#.
So you will have to declare the layout this way:

[StructLayout(LayoutKind.Explicit)]
struct scData
{
[FieldOffset(0)] public clsByte2 b2_0;
[FieldOffset(2)] public clsByte2 b2_1;
[FieldOffset(4)] public clsByte2 b2_2;
[FieldOffset(6)] public clsByte2 b2_3;
[FieldOffset(8)] public clsByte2 b2_4;
[FieldOffset(10)] public clsByte2 b2_5;
[FieldOffset(12)] public clsByte1 b1_0;
...
}

Sergei

[snip]
 
C

Christian Kaiser

Oh well, thanks to you both...

I guess I'll use C++ for that part. C# just cannot do it.

I can make functions to "divide" the input stream into the different fields,
but that would be more work than defining a simple structure layout, which
would automatically do that.

Christian
 
C

Christian Kaiser

Assuming I do the "data gathering" code in C++ now, which is the best way to
connect the C++ part to the c# application (which is responsible for the
user interface)?

- directly in the application (is that possible, to mix C++ and C# source
files)? Sorry, I'm new to .NET as you see, but not at all new into Windows
programming..
- using an interface to define a "data record" interface, or an abstract
class to define the interface (or is that a philosophical question, as
there's not too much of a difference as far as I see)?

Thanks,

Christian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top