关于含数组返回值方法的结构体成员引用的疑问

陌上_桑 2019-05-22 10:08:19
问题是这样的
我想建一个共用的方法,方法的参数是结构体,其中结构体比较特殊,之前也问过一些问题,最终也没能解决问题。
结构体类似如下:

[StructLayout(LayoutKind.Explicit)]
public struct Union
{
[FieldOffset(0)]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.Struct)]
public bool[] bit;
[FieldOffset(0)]
public int BitComb;
}

一开始准备建立联合的时候是因为操作同一片地址,给BitComb赋值之后,直接就等于给32个bit也赋值了:


结果也是没法达到目的;编译都能通过,就是运行的时候直接就崩溃了。

然后试着如下的方式:

public struct U
{
public int BitComb;
public bool[] bit()
{
bool[] bit = new bool[32];
for (int i = 1;i <= 32;i++)
{
int idx_bool = i - 1;
int cardinal = 1;
bit[idx_bool] = (BitComb & (cardinal<<idx_bool)) == 0 ? false:true;
}
return bit;
}
}

结果在引用的时候不知道怎么引用bit
引用的程序:

public void DataRead(U type1,U type2)
{
int cur_Node = Globals.Tags.addr_node.Value;
switch(cur_Node)
{
case 1:
//pressure set value read
if(type1.bit[0])
{
if (type2.bit[0])
{
Globals.Tags.sv_prepressure801.Read();
DvInfo.wrSV_float[0] = Globals.Tags.sv_prepressure801.Value;
}
if (type2.bit[1])
{
Globals.Tags.sv_brushpressure801.Read();
DvInfo.wrSV_float[1] = Globals.Tags.sv_brushpressure801.Value;
}
if (type2.bit[2])
{
Globals.Tags.sv_postpressure801.Read();
DvInfo.wrSV_float[2] = Globals.Tags.sv_postpressure801.Value;
}
}

//counter & time set value read
if(type1.bit[1])
{
if(type2.bit[0])
{
Globals.Tags.sv_brushcnt801.Read();
DvInfo.wrSV_int[0] = Globals.Tags.sv_brushcnt801.Value;
}
if(type2.bit[1])
{
Globals.Tags.sv_pretime801.Read();
DvInfo.wrSV_int[1] = Globals.Tags.sv_pretime801.Value;
}
if(type2.bit[2])
{
Globals.Tags.sv_brushtime801.Read();
DvInfo.wrSV_int[2] = Globals.Tags.sv_brushtime801.Value;
}
if(type2.bit[3])
{
Globals.Tags.sv_posttime801.Read();
DvInfo.wrSV_int[3] = Globals.Tags.sv_posttime801.Value;
}
}

//password set value read
if(type1.bit[2])
{
if(type2.bit[0])
{
Globals.Tags.pw801_Admin.Read();
DvInfo.wrPW[0] = Globals.Tags.pw801_Admin.Value;
}
if(type2.bit[1])
{
Globals.Tags.pw801_Eng.Read();
DvInfo.wrPW[1] = Globals.Tags.pw801_Eng.Value;
}
if(type2.bit[2])
{
Globals.Tags.pw801_Oper.Read();
DvInfo.wrPW[2] = Globals.Tags.pw801_Oper.Value;
}
}

// button trig read
if(type1.bit[3])
{
if(type2.bit[0])
{
Globals.Tags.btn_prepurge801.Read();
DvInfo.wBTN[0] = Globals.Tags.btn_prepurge801.Value;
}
if(type2.bit[1])
{
Globals.Tags.btn_brush801.Read();
DvInfo.wBTN[1] = Globals.Tags.btn_brush801.Value;
}
if(type2.bit[2])
{
Globals.Tags.btn_postpurge801.Read();
DvInfo.wBTN[2] = Globals.Tags.btn_postpurge801.Value;
}
}

//current parameter read
if(type1.bit[4])
{
if(type2.bit[0])
{
Globals.Tags.cv_pressure801.Read();
DvInfo.rCV_float[0] = Globals.Tags.cv_pressure801.Value;
}
if(type2.bit[1])
{
Globals.Tags.cv_flowm801.Read();
DvInfo.rCV_float[1] = Globals.Tags.cv_flowm801.Value;
}
if(type2.bit[2])
{
Globals.Tags.cv_flowb801.Read();
DvInfo.rCV_float[2] = Globals.Tags.cv_flowb801.Value;
}
if(type2.bit[3])
{
Globals.Tags.cv_sound801.Read();
DvInfo.rCV_float[3] = Globals.Tags.cv_sound801.Value;
}
}

//cycle count and time current value read
if(type1.bit[5])
{
if(type2.bit[0])
{
Globals.Tags.cv_brushcnt801.Read();
DvInfo.rCV_int[0] = Globals.Tags.cv_brushcnt801.Value;
}
if(type2.bit[1])
{
Globals.Tags.cv_pretime801.Read();
DvInfo.rCV_int[1] = Globals.Tags.cv_pretime801.Value;
}
if(type2.bit[2])
{
Globals.Tags.cv_brushtime801.Read();
DvInfo.rCV_int[2] = Globals.Tags.cv_brushtime801.Value;
}
if(type2.bit[3])
{
Globals.Tags.cv_posttime801.Read();
DvInfo.rCV_int[3] = Globals.Tags.cv_posttime801.Value;
}
}

//button lamp read
if(type1.bit[6])
{
if(type2.bit[0])
{
Globals.Tags.lp_prepurge801.Read();
DvInfo.rLP[0] = Globals.Tags.lp_prepurge801.Value;
}
if(type2.bit[1])
{
Globals.Tags.lp_brush801.Read();
DvInfo.rLP[1] = Globals.Tags.lp_brush801.Value;
}
if(type2.bit[2])
{
Globals.Tags.lp_postpurge801.Read();
DvInfo.rLP[2] = Globals.Tags.lp_postpurge801.Value;
}
}

//signal read
if(type1.bit[7])
{
if(type2.bit[0])
{
Globals.Tags.sig_purge801.Read();
DvInfo.rSIG[0] = Globals.Tags.sig_purge801.Value;
}
if(type2.bit[1])
{
Globals.Tags.sig_brush801.Read();
DvInfo.rSIG[1] = Globals.Tags.sig_brush801.Value;
}
}

//
break;
default:
if(type1.bit[0])
{
if(type2.bit[0])
{
DvInfo.wrSV_float[0] = Convert.ToSingle(System.Math.PI);
}
if(type2.bit[1])
{
DvInfo.wrSV_float[1] = 2*DvInfo.wrSV_float[1];
}
if(type2.bit[2])
{
DvInfo.wrSV_float[2] = Convert.ToSingle(1.5*DvInfo.wrSV_float[1]);
}
if(type2.bit[3])
{
DvInfo.wrSV_float[3] = Convert.ToSingle(0.5*DvInfo.wrSV_float[1]);
}
}
break;
}
}

很显然,这里的type1.bit[0]以及type2.bit[0]等无法通过编译。
这里的bit到底该如何引用?
...全文
147 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2019-05-22
  • 打赏
  • 举报
回复
public bool[] bit() 说明你是一个方法 所以bit()获得了bool[],然后制定下标就是 bit()[index]
stherix 2019-05-22
  • 打赏
  • 举报
回复
type1.bit()[0]
stherix 2019-05-22
  • 打赏
  • 举报
回复
引用 8 楼 陌上_桑 的回复:
[quote=引用 7 楼 stherix 的回复:] 你可以写个这个扩展方法对int位进行操作
    
public static class BitExtension
    {
        public static int SetBit(this int data, int pos, bool value)
        {
            if (value)
                return data | (1 << pos);
            else
                return data & ~(1 << pos);
        }

        public static int GetBit(this int data, int pos)
        {
            return (data >> pos) & 1;
        }
    }
要注意的是SetBit并不会修改int本身的值,而是返回一个新值
这是针对解决系统崩溃问题还是说修改方法?[/quote] 因为涉及到和硬件通讯,所以崩溃原因我也不知道
陌上_桑 2019-05-22
  • 打赏
  • 举报
回复
引用 7 楼 stherix 的回复:
你可以写个这个扩展方法对int位进行操作
    
public static class BitExtension
    {
        public static int SetBit(this int data, int pos, bool value)
        {
            if (value)
                return data | (1 << pos);
            else
                return data & ~(1 << pos);
        }

        public static int GetBit(this int data, int pos)
        {
            return (data >> pos) & 1;
        }
    }
要注意的是SetBit并不会修改int本身的值,而是返回一个新值
这是针对解决系统崩溃问题还是说修改方法?
stherix 2019-05-22
  • 打赏
  • 举报
回复
你可以写个这个扩展方法对int位进行操作 public static class BitExtension { public static int SetBit(this int data, int pos, bool value) { if (value) return data | (1 << pos); else return data & ~(1 << pos); } public static int GetBit(this int data, int pos) { return (data >> pos) & 1; } } 要注意的是SetBit并不会修改int本身的值,而是返回一个新值
陌上_桑 2019-05-22
  • 打赏
  • 举报
回复
引用 5 楼 stherix 的回复:
[quote=引用 4 楼 陌上_桑 的回复:] [quote=引用 1 楼 stherix 的回复:] type1.bit()[0]
那么就第一种方法:

[StructLayout(LayoutKind.Explicit)]
    public struct Union
    {
        [FieldOffset(0)]
        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.Struct)]
        public bool[] bit;          
        [FieldOffset(0)]
        public int BitComb;         
    }
能达到对BitComb赋值后,bool数组的值就已经出来的效果吗?[/quote] 不能 c#里bool是4字节大小,无法对应到位[/quote] 哦,这样啊。 后来我在其他界面引用了之前定义的方法,结果运行直接崩溃了,能看看怎么回事吗?连Log都没有,无从查起啊。
stherix 2019-05-22
  • 打赏
  • 举报
回复
引用 4 楼 陌上_桑 的回复:
[quote=引用 1 楼 stherix 的回复:] type1.bit()[0]
那么就第一种方法:

[StructLayout(LayoutKind.Explicit)]
    public struct Union
    {
        [FieldOffset(0)]
        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.Struct)]
        public bool[] bit;          
        [FieldOffset(0)]
        public int BitComb;         
    }
能达到对BitComb赋值后,bool数组的值就已经出来的效果吗?[/quote] 不能 c#里bool是4字节大小,无法对应到位
陌上_桑 2019-05-22
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
type1.bit()[0]
那么就第一种方法:

[StructLayout(LayoutKind.Explicit)]
    public struct Union
    {
        [FieldOffset(0)]
        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.Struct)]
        public bool[] bit;          
        [FieldOffset(0)]
        public int BitComb;         
    }
能达到对BitComb赋值后,bool数组的值就已经出来的效果吗?
陌上_桑 2019-05-22
  • 打赏
  • 举报
回复
引用 2 楼 正怒月神 的回复:
public bool[] bit() 说明你是一个方法 所以bit()获得了bool[],然后制定下标就是 bit()[index]
现在在另外一个Screen(Conpact .NET开发)的脚本里输入以下代码:

public partial class tempdsScr
    {
		private Timer t;
		private float[] ValStr = {0,0,0,0};		
		public void StartTimer()
		{
			t = new Timer();
			t.Enabled = true;
			t.Interval = Globals.Tags.refreshCT.Value;
			t.Tick += myTick;
		}
		public void myTick(object obj,EventArgs ea)
		{
			
			if(!Globals.Tags.flag_LoginOpen.Value)
			{
				ValStr = Globals.UserModule.DevSts();			
				disp_Pressure.Value = ValStr[0];
				disp_Flow1.Value = ValStr[1];
				disp_Flow2.Value = ValStr[2];
				disp_Sound.Value = ValStr[3];
				string exeInd = Globals.UserModule.ExecuteInd();
				executionIndicate.Text = exeInd;
				U t1 = new U();				
				U t2 = new U();
				t1.BitComb = 1;
				t2.BitComb = 15;
				//executionIndicate.FontColor = Color.Beige;
				Globals.UserModule.DataRead(t1,t2);
				//AnalogNumeric.Value = Globals.UserModule.DvInfo.wrSV_float[0];
				//AnalogNumeric.Value = Globals.UserModule.DvInfo.wrSV_float[1];
				//AnalogNumeric.Value = Globals.UserModule.DvInfo.wrSV_float[2];
				//AnalogNumeric.Value = Globals.UserModule.DvInfo.wrSV_float[3];
				
				
			}
		}
		void tempdsScr_Opened(System.Object sender, System.EventArgs e)
		{
			// define prefix & suffix
			disp_Pressure.Prefix = "当前气压:";
			disp_Pressure.Suffix = " psi";
			disp_Flow1.Prefix = "主管道流量:";
			disp_Flow1.Suffix = " l/min";
			disp_Flow2.Prefix = "支管道流量:";
			disp_Flow2.Suffix = " l/min";
			disp_Sound.Prefix = "汽笛声强:";
			disp_Sound.Suffix = " dB";
			//type1.BitComb = 1;
			//type2.BitComb = 15;
			
			StartTimer();		
			
		}
		
		void tempdsScr_Closed(System.Object sender, System.EventArgs e)
		{
			t.Enabled = false;
			t.Tick -= myTick;
		}
	}
结果运行起来直接崩溃了。 什么原因?但是把 Globals.UserModule.DataRead(t1,t2); 注释掉就不会有问题。 这里的DataRead就是上文的DataRead

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧