バイト配列をクラスまたは構造体に変換する際に問題が発生しました。クラスは次のようになります。
[Serializable()]
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class General {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Defines.CENTR_NAME_LENGTH + 1)] byte[] centralName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Defines.PROJECT_NAME_LENGTH + 1)] byte[] projectName;
byte misc;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] byte[] accessCode2;
byte transmActive;
byte transmHour;
byte transmMin;
[MarshalAs(UnmanagedType.U1)] public int Cp;
[MarshalAs(UnmanagedType.U1)] public int Rp;
[MarshalAs(UnmanagedType.U1)] public int Lcd;
[MarshalAs(UnmanagedType.U1)] public int Relais;
[MarshalAs(UnmanagedType.U1)] public int Pr;
[MarshalAs(UnmanagedType.U1)] public int Sc;
byte rd;
byte reserve1;
[MarshalAs(UnmanagedType.U1)] public int LocalCentrId;
[MarshalAs(UnmanagedType.U1)] public int PrinterSel;
[MarshalAs(UnmanagedType.U1)] public int Slave1;
[MarshalAs(UnmanagedType.U1)] public int Slave2;
[MarshalAs(UnmanagedType.U1)] public int Slave3;
[MarshalAs(UnmanagedType.U1)] public int Master;
[MarshalAs(UnmanagedType.U1)] public int AlarmRepeat;
[MarshalAs(UnmanagedType.U1)] public int FaultRepeat;
[MarshalAs(UnmanagedType.U1)] public int ResetSil1;
[MarshalAs(UnmanagedType.U1)] public int ResetSil2;
[MarshalAs(UnmanagedType.U1)] public int EvacDelayed1;
[MarshalAs(UnmanagedType.U1)] public int EvacDelayed2;
[MarshalAs(UnmanagedType.U1)] public int Led1;
[MarshalAs(UnmanagedType.U1)] public int Led2;
[MarshalAs(UnmanagedType.U1)] public int GenControl;
[MarshalAs(UnmanagedType.U1)] public int ExtraGenControl;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Defines.MAX_NMB_SIL_CONTROL)] byte[] silenceControls ;
byte autoResetFault;
byte autoResetSC;
[MarshalAs(UnmanagedType.U1)] public int InitEvacDelay;
[MarshalAs(UnmanagedType.U1)] public int SilenceEvacOff;
byte summerTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] byte[] accessCode1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] byte[] btPinCode;
public string CentralName { get { return Encoding.ASCII.GetString(centralName); } set { centralName = Encoding.ASCII.GetBytes(value); } }
public string ProjectName { get { return Encoding.ASCII.GetString(projectName); } set { projectName = Encoding.ASCII.GetBytes(value); } }
public bool BackBeep {
get {
return (misc & 0x01) != 0x00;
}
set {
if (value) {
misc |= 0x01;
} else {
misc ^= 0x01;
}
}
}
public bool StartStopEvac {
get {
return (misc & 0x02) != 0x00;
}
set {
if (value) {
misc |= 0x02;
} else {
misc ^= 0x02;
}
}
}
public bool GenBehEvacKey {
get {
return (misc & 0x04) != 0x00;
}
set {
if (value) {
misc |= 0x04;
} else {
misc ^= 0x04;
}
}
}
public bool GenBehEvacDet {
get {
return (misc & 0x08) != 0x00;
}
set {
if (value) {
misc |= 0x08;
} else {
misc ^= 0x08;
}
}
}
public bool EvacDelayed {
get {
return (misc & 0x10) != 0x00;
}
set {
if (value) {
misc |= 0x10;
} else {
misc ^= 0x10;
}
}
}
public bool SirService {
get {
return (misc & 0x20) != 0x00;
}
set {
if (value) {
misc |= 0x20;
} else {
misc ^= 0x20;
}
}
}
public bool ResetSilService {
get {
return (misc & 0x40) != 0x00;
}
set {
if (value) {
misc |= 0x40;
} else {
misc ^= 0x40;
}
}
}
public string AccessCode1 { get { return Encoding.ASCII.GetString(accessCode1); } set { accessCode1 = Encoding.ASCII.GetBytes(value); } }
public string AccessCode2 { get { return Encoding.ASCII.GetString(accessCode2); } set { accessCode2 = Encoding.ASCII.GetBytes(value); } }
public bool EvacDirect { get { return transmActive == 0x01; } set { transmActive = (Byte)(value ? 0x01 : 0x00); } }
public TimeSpan EvacDirectTime { get { return new TimeSpan(transmHour, transmMin, 0); } set { transmHour = (Byte)value.Hours; transmMin = (Byte)value.Minutes; } }
public bool Rd { get { return rd == 0x01; } set { rd = (value ? (Byte)0x01 : (Byte)0x00); } }
public List<int> SilenceControl {
get {
List<int> retVal = new List<int>();
if (silenceControls != null) {
foreach (byte b in silenceControls) {
retVal.Add(b);
}
}
return retVal;
}
set {
silenceControls = new byte[Defines.MAX_NMB_SIL_CONTROL];
for (int t = 0; t < Defines.MAX_NMB_SIL_CONTROL && t < value.Count; ++t) {
silenceControls[t] = (Byte)value[t];
}
}
}
public bool AutoResetFault { get { return autoResetFault == 0x01; } set { autoResetFault = (Byte)(value ? 0x01 : 0x00); } }
public bool AutoResetPower { get { return autoResetSC == 0x01; } set { autoResetSC = (Byte)(value ? 0x01 : 0x00); } }
public bool SummerTime { get { return summerTime == 0x01; } set { summerTime = (Byte)(value ? 0x01 : 0x00); } }
public string BtPinCode { get { return Encoding.ASCII.GetString(btPinCode); } set { btPinCode = Encoding.ASCII.GetBytes(value); } }
public General() {
Console.WriteLine("Create General");
SetDefault();
}
public void SetDefault() {
CentralName = "MD2400";
ProjectName = "Limotec";
Cp = 1;
Rp = 0;
Lcd = 0;
Relais = 1;
Pr = 0;
Sc = 1;
Rd = true;
BackBeep = false;
AccessCode1 = "654321";
AccessCode2 = "123456";
EvacDirect = false;
EvacDirectTime = new TimeSpan( 0, 0, 0 );
BtPinCode = "1111111111111111";
SummerTime = true;
GenControl = 1;
ExtraGenControl = 0;
SilenceControl.Add( 3 );
InitEvacDelay = 2;
EvacDelayed = false;
StartStopEvac = false;
SirService = false;
ResetSilService = false;
GenBehEvacKey = true;
GenBehEvacDet = true;
Master = 32;
Slave1 = 0;
Slave2 = 0;
Slave3 = 0;
AlarmRepeat = 0;
FaultRepeat = 0;
ResetSil1 = 0;
ResetSil2 = 0;
Led1 = 0;
Led2 = 0;
EvacDelayed1 = 0;
EvacDelayed2 = 0;
LocalCentrId = 0;
AutoResetFault = true;
AutoResetPower = true;
}
[OnDeserialized()]
internal void OnDeserialized(StreamingContext contect) {
Config.Singleton.Log.Info( string.Format( "General loaded: {0} {1}", CentralName, ProjectName ) );
}
}
Marshall.SizeOf(typeof(General))を実行すると、ArgumentExceptionが発生します。サイズやオフセットは計算できません。
同じクラスでプライベート変数とパブリックプロパティを使用する場合、問題はありますか?プロパティは、変数をより便利なものに変換するためだけのものです。(バイト配列から文字列へ)
Marshal.PtrToStructureを使用してバイト配列をクラスに配置できるようにするにはどうすればよいですか?