问题描述
读取PLC中的结构体时,总是提示:尝试读取或写入受保护的内存。这通常指示其他内存已损坏,但是,我把string[]改成char[]时,可以读到300个单字符,是数据类型的问题么?usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Runtime.InteropServices;usingTwinCAT.Ads;usingSystem.IO;namespaceCodeMsg{publicpartialclassForm1:Form{publicTcAdsClientadsClient;privateintCodeTxt1;[StructLayout(LayoutKind.Sequential,Pack=0)]//分布结构体内内存地址的位置publicclassCodeTxtStru{[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst=300,ArraySubType=UnmanagedType.BStr)]publicstring[]CodeTxt=newstring[300];}privatevoidFillCodeTXT(CodeTxtStruCTstructure){for(inti=0;i<300;i++){app.CodeTxt[i]=CTstructure.CodeTxt[i];}}publicForm1(){InitializeComponent();adsClient=newTcAdsClient();try{adsClient.Connect("192.168.1.11.1.1",801);CodeTxt1=adsClient.CreateVariableHandle("MAIN.Codemsg");}catch(Exceptionex){MessageBox.Show(ex.Message);}}privatevoidbutton1_Click(objectsender,EventArgse){FillCodeTXT((CodeTxtStru)adsClient.ReadAny(CodeTxt1,typeof(CodeTxtStru)));}privatevoidForm1_Load(objectsender,EventArgse){for(inti=0;i<300;i++){DataGridViewRowdgvr=newDataGridViewRow();foreach(DataGridViewColumncinthis.Codedata.Columns){dgvr.Cells.Add(c.CellTemplate.Clone()asDataGridViewCell);}dgvr.Cells[0].Value=app.CodeTxt[i];this.Codedata.Rows.Add(dgvr);}}}}PLC中的结构体定义:TYPECodeMSG:STRUCTCodeTxt:ARRAY[1..300]OFSTRING(32);END_STRUCTEND_TYPEMAIN中引用:PROGRAMMAINVARCodemsg:CodeMSG;END_VAR求高手解答!
解决方案
解决方案二:
我觉得有可能是PLC里面设置了string是定长的:string(32)的问题那么我在[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst=300,ArraySubType=UnmanagedType.BStr)]publicstring[]CodeTxt=newstring[300];这一句时改为publicStringBuilder[CodeTxt=newStringBuilder[300];时,如何设置StringBuilder[]的定长为32呢?
解决方案三:
这个问题,你应该问PLC厂家要通信协议啊自己瞎猜?
解决方案四:
我有ADS通信资料,但是里面只有除string[]外其它所有类型的资料,独独没有string[]的,同样的结构体用int[]、char[]实现起来都没有问题,就是string[]出错。。。单独一条一条的读,用string变量接收没有问题,但是300条……太多了!要写300个句柄!
解决方案五:
CodeTxt:ARRAY[1..300]OFSTRING(32);---------32在哪儿?
解决方案六:
引用4楼ghao0的回复:
CodeTxt:ARRAY[1..300]OFSTRING(32);---------32在哪儿?
这是PLC程序中的语句,是给STRING设置定长。这段程序是通过ADS通讯从PCL程序里读取数据,C#里的STRING不是变长的么?如果要在C#里设置字符数定长的string[]要怎么设置?
解决方案七:
引用2楼Z65443344的回复:
这个问题,你应该问PLC厂家要通信协议啊自己瞎猜?
大神,我好多提问都是你回答的,再问个问题呗,如果要在C#里设置字符数定长的string[]要怎么设置?比如:一个字符串数组有300个变量,每个字符串变量固定长度32个字符。
解决方案八:
C#里字符串是变长的,因为字符串变量是个引用类型在C++里,字符串和字符数组是可以通用的,C#不可以,但是可以用函数转换你可以定义长度为32的字符数组,然后把它转换成字符串
解决方案九:
引用7楼Z65443344的回复:
C#里字符串是变长的,因为字符串变量是个引用类型在C++里,字符串和字符数组是可以通用的,C#不可以,但是可以用函数转换你可以定义长度为32的字符数组,然后把它转换成字符串
你的意思是string[]st=newstring[32]{"123","234","555"……(32个)}然后把它变成字符串,这我会。我的意思是string[]st=newstring[300]{"123456……32",“123456……32”,……(300个32个字符的字符串)}