| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256 | using Newtonsoft.Json.Linq;using System;using System.Collections;using System.Collections.Generic;using System.Drawing;using System.Dynamic;using System.Linq;using System.Reflection;using System.Runtime.InteropServices;using System.Runtime.Serialization;using System.Security.Policy;using System.Text;using System.Text.RegularExpressions;using System.Threading.Tasks;using System.Windows.Forms;using System.Xml.Linq;using static System.Net.Mime.MediaTypeNames;using static System.Windows.Forms.VisualStyles.VisualStyleElement;namespace EIP_Protocol{    #region MES与PLC通讯结构    public enum eMachineState:short    {        Uninitialized=0,     //未初始化状态        Initializing,        //初始化中...        Initialized,         //初始化完成        Running,             //运行中        Paused,              //暂停状态        Fault,               //故障状态        Alarm                //报警状态    }    public enum eMesCmd:byte    {        none=0,        InStation = 1,        //1:工站进站申请        OutStation =2         //2:工站出站申请    }    public enum eAgvCmd    {        RequestPassingIn = 1,           // = 1, AGV请求进料        ConfirmPassInFinish = 2,        //= 2, AGV请求进料完成确认        RequestPassingOut = 3,          //=3, AGV请求出料        ConfrimPassingOutFinish = 4     //= 4, AGV请求出料完成确认            }    public struct XiaoMiParm    {        public string workstation { get; set; }  //装备编码                      public string stationCode { get; set; }  //工站ID               public string deviceCode { get; set; }   //工位编码          }    //图⽚命名需要遵循⼩⽶标准    //[项⽬]_[⼯站]_[SN]_[物料-功能]_[测试时间]_[定位/检测/测量结果]_[是否原图-当前第⼏张-共⼏张]    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct CommandToPLC    {        [MarshalAs(UnmanagedType.U1)]        public byte cmd;                //1:AGV请求进料 2:AGV请求进料完成确认   3:AGV请求出料  4:AGV请求出料完成确认   PLC:成功回被PC清零        [MarshalAs(UnmanagedType.I2)]        public short cmdParam;          //1:左边接口    2:右边接口        [MarshalAs(UnmanagedType.I2)]        public short cmdResult;         //指令执行结果 1:OK   110:失败    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct CommandFromPLC    {        [MarshalAs(UnmanagedType.U1)]        public byte cmd;                //1:工站进站申请  2:工站出站申请        [MarshalAs(UnmanagedType.I2)]        public short cmdParam;          //指令参数        [MarshalAs(UnmanagedType.I2)]        public short cmdResult;         //指令执行结果 1:OK   110:失败    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP10_From_PLC    {        [MarshalAs(UnmanagedType.I4)]        public int nThrowCount;                               //抛料次数        [MarshalAs(UnmanagedType.R4)]        public float fCleanAirPress;                          //清洁气压        [MarshalAs(UnmanagedType.R4)]        public float fCleanSpeed;                             //清洁速度mm/s        [MarshalAs(UnmanagedType.R4)]        public float fWindBladeHeight;                        //风刀高度mm        [MarshalAs(UnmanagedType.R4)]        public float fCleanTime;                              //清洁时间S        [MarshalAs(UnmanagedType.I4)]        public int nCleanCount;                               //清洁次数    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP10_DataSet_t    {        [MarshalAs(UnmanagedType.I4)]        public int nThrowCount;                               //抛料次数        [MarshalAs(UnmanagedType.R4)]        public float fCleanAirPress;                          //清洁气压        [MarshalAs(UnmanagedType.R4)]        public float fCleanSpeed;                             //清洁速度mm/s        [MarshalAs(UnmanagedType.R4)]        public float fWindBladeHeight;                        //风刀高度mm        [MarshalAs(UnmanagedType.R4)]        public float fCleanTime;                              //清洁时间S        [MarshalAs(UnmanagedType.I4)]        public int nCleanCount;                               //清洁次数        [MarshalAs(UnmanagedType.I4)]        public int nRemainCount;                             //外壳体余料数    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct IoT_DataSet_t    {        [MarshalAs(UnmanagedType.I2)]        public short machineState;         //设备状态          [MarshalAs(UnmanagedType.I2)]        public short work_type;            //作业类型:=1 PRESSURE_TEST(压测),=2 POINT_CHECK(点检),=3 OUT_STATION(正常跑料数据)        [MarshalAs(UnmanagedType.I2)]        public short testStatus;            //测试状态:=1 PASS  0=FAIL        [MarshalAs(UnmanagedType.I2)]        public short beatAction;            //节拍动作 1:上料开始  2:上料结束 3                                            //:作业开始  4:作业结束   5:下料开始  6:下料结束        [MarshalAs(UnmanagedType.I2)]       //节拍返回 1:OK   2:NG           public short beatReturn;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]   //一个单独的位代表一个报警32*10=320        public uint[] fault_codes;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP20_DataSet_t    {        [MarshalAs(UnmanagedType.I4)]        public int nThrowCount;                              //抛料次数        [MarshalAs(UnmanagedType.I4)]        public int nRemainCount;                             //上盖余料数                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]        public float[] nCeJuData;           //测距    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP30_DataSet_t                            //站数据集    {        [MarshalAs(UnmanagedType.R4)]        public float fGlueSupplySpeed;                       //供胶速度        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPress;                           //AB管气压        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPressDiff;                       //AB管气压差        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]        public float[] fMesHeightInfos;                      //产品测高信息--点胶前的测高(mm)        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]        public float[] fIntervalWeights;                     //可能没有:定期称重数据 A胶,B胶        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]        public float[] fRemainGlues;                         //剩余胶量A:0 B:1    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP30_TestData_t                            //站数据集    {        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPress;             //AB管气压        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPressMax;          //AB管气压(最大值)        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPressMin;          //AB管气压(最小值)        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPressDiff;         //AB管气压差        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPressDiffMax;       //AB管气压差(最大值)        [MarshalAs(UnmanagedType.R4)]        public float fAB_AirPressDiffMin;       //AB管气压差(最小值)    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP30_stnDataSet_t    {        public BarcodeSet_t BarcodeSet;        //条码集合        public CommandFromPLC mesCommFrmPLC;   //MES通讯        public OP30_DataSet_t mesData;        public IoT_DataSet_t iotData;        public OP30_TestData_t testData;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP40_DataSet_t    {        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]        public float[] fGluePosX;                                 //胶线位置X偏差        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]        public float[] fGluePosY;                                 //胶线位置Y偏差        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]        public float[] fGlue_Areas;                              //胶线面积        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]        public float[] fGlue_Heights;                            //胶线高度        [MarshalAs(UnmanagedType.I4)]        public int nResult;                                       //胶线检测结果 1:OK  非1:NG        //public Image  TestPic;                                  //测试照片    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP40_TestData_t  //测试项    {        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]        public float[] fGlue_Areas;             //胶线面积        [MarshalAs(UnmanagedType.R4)]        public float fGlue_AreasMax;          //胶线面积(最大值)        [MarshalAs(UnmanagedType.R4)]        public float fGlue_AreasMin;          //胶线面积(最小值)        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]        public float[] fGlue_Heights;         //胶线高度        [MarshalAs(UnmanagedType.R4)]        public float fGlue_HeightsMax;       //胶线高度(最大值)        [MarshalAs(UnmanagedType.R4)]        public float fGlue_HeightsMin;       //胶线高度(最小值)    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP50_DataSet_t    {        [MarshalAs(UnmanagedType.I4)]        public int nIsAddPCBAsmOK;                                //是否组装到位        [MarshalAs(UnmanagedType.I4)]        public int nHaveAddPCB;                                   //是否有ADD板        [MarshalAs(UnmanagedType.R4)]        public float fForceAddPCB;                                //装ADD板的压力        [MarshalAs(UnmanagedType.I4)]        public int nRemainCount;                                  //ADD板余料数    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP50_TestData_t    {        [MarshalAs(UnmanagedType.R4)]        public float fForceAddPCB;                                //装ADD板的压力        [MarshalAs(UnmanagedType.R4)]        public float fForceAddPCBMax;                                   //装ADD板的压力(最大值)        [MarshalAs(UnmanagedType.R4)]        public float fForceAddPCBMin;                                //装ADD板的压力(最小值)    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP60_DataSet_t    {        [MarshalAs(UnmanagedType.I4)]        public int nIsTopCoverAsmOK;                             //是否组装到位        [MarshalAs(UnmanagedType.I4)]        public int nHaveTopCover;                                //是否有上盖板        [MarshalAs(UnmanagedType.R4)]        public float fForceTopCover;                             //装上盖板的压力    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP70_DataSet_t    {        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]        public float[] fScrewTimes;                                  //锁附时间 PLC 14颗螺丝 预留6        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]        public short[] nScrewOrders;                                 //锁附顺序 PLC  锁螺丝的标号        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]        public short[] nScrewResults;                                 //锁附结果 PLC        [MarshalAs(UnmanagedType.I4)]        public int nRemainCount;                                      //螺丝余料数    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP70_ScrewDataSet_t    {        [MarshalAs(UnmanagedType.R4)]        public float fTorque;                             //上位机传到PLC的锁螺丝扭力  每次读到阿特拉斯的数据都传一次        [MarshalAs(UnmanagedType.R4)]        public float fCircles;                            //上位机传到PLC的锁螺丝圈数  每次读到阿特拉斯的数据都传一次    }    public class OP70_PC_CollectDataSet_t    {        //需要自己收集        public float[] fScrewTorques;                         //锁附扭力        public float[] fScrewCircles;                         //锁附圈数        public float[][] fTorqueCurve;                        //扭力曲线    }    public struct OP70_stnDataSet_t    {        public BarcodeSet_t BarcodeSet;        //条码集合        public CommandFromPLC mesCommFrmPLC;   //MES通讯        public OP70_DataSet_t mesData;        public IoT_DataSet_t iotData;        public OP70_ScrewDataSet_t screwDataToPLC;  //传到PLC的锁螺丝数据,用于HMI显示用    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct BarcodeSet_t    {        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]     //载具条码        public string strCarrierBarcode;        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)]    //产品条码        public string strProductBarcode;        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)]    //工位零部件条码        public string strPartBarcode;        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)]    //PCB        public string strPCBBarcode;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP10_MesData_t    {        public BarcodeSet_t BarcodeSet;         //条码集合        public CommandToPLC agvCommToPLC;       //AGV通讯        public CommandFromPLC mesCommFrmPLC;    //MES通讯        public OP10_DataSet_t mesData;        public IoT_DataSet_t iotData;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP20_MesData_t    {        public BarcodeSet_t BarcodeSet;       //条码集合        public CommandToPLC agvCommToPLC;     //AGV通讯        public CommandFromPLC mesCommFrmPLC;  //MES通讯        public OP20_DataSet_t mesData;        public IoT_DataSet_t iotData;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP30_MesData_t    {        public OP30_stnDataSet_t Left;        public OP30_stnDataSet_t Right;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP40_MesData_t    {        public BarcodeSet_t BarcodeSet;        //条码集合        public CommandFromPLC mesCommFrmPLC;   //MES通讯        public OP40_DataSet_t mesData;            public IoT_DataSet_t iotData;        public OP40_TestData_t testData;  //测试项    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP50_MesData_t    {        public BarcodeSet_t BarcodeSet;     //条码集合        public CommandToPLC agvCommToPLC;   //AGV通讯        public CommandFromPLC mesCommFrmPLC;  //MES通讯        public OP50_DataSet_t mesData;        public IoT_DataSet_t iotData;        public OP50_TestData_t testData;  //测试项    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP60_MesData_t    {        public BarcodeSet_t BarcodeSet;        //条码集合        public CommandFromPLC mesCommFrmPLC;   //MES通讯        public OP60_DataSet_t mesData;        public IoT_DataSet_t iotData;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP70_iotDataSet_t    {        public IoT_DataSet_t Left;        public IoT_DataSet_t Right;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP70_MesData_t    {        public OP70_stnDataSet_t Left;        public OP70_stnDataSet_t Right;    }    public struct OP80_DataSet_t    {        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]        public float[] fScrewHeights;                               //螺丝高度 PLC 14颗螺丝 预留6        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]        public short[] nScrewResults;                               //螺丝检测结果 PLC   1:OK   0:NG    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP80_MesData_t    {        public BarcodeSet_t BarcodeSet;         //条码集合        public CommandFromPLC mesCommFrmPLC;    //MES通讯        public OP80_DataSet_t mesData;        public IoT_DataSet_t iotData;    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP90_DataSet_t    {        [MarshalAs(UnmanagedType.I4)]        public int nThrowCount;                                 //抛料次数         [MarshalAs(UnmanagedType.I4)]        public int nRemainCount;                               //料箱余料数    }    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]    public struct OP90_MesData_t    {        public BarcodeSet_t BarcodeSet;           //条码集合        public CommandToPLC agvCommToPLC;         //AGV通讯        public CommandFromPLC mesCommFrmPLC;      //MES通讯        public OP90_DataSet_t mesData;        public IoT_DataSet_t iotData;    }    #endregion  MES与PLC通讯结构    public class Inovance_EIP    {        private string strTagPrefix = "Application.GVL.";  //标签前缀,80站是Application.GVL_HMI.,不知道为什么反正就是这样        private object m_objLock = new object();        bool isStart = false;        string strClaimedComputerIP = "";   //PC的IP地址 - private实际IP        private int m_nInstanceId = 0;      //实例ID        public bool m_bConnected = false;        public string _pcIPStr = string.Empty;   //PC的IP地址        public string _plcIPStr = string.Empty;  //PLC的IP地址        public bool IsConnected        {            get { return m_bConnected; }        }        public void Config_TagPrefix(string TagPrefix)        {            strTagPrefix = TagPrefix;        }        #region 自定义的结构        public enum ERROR_NO : int        {            ERR_EIP_STOPED = -2,//协议栈未开启            OTHER_ERROR = -1,            SUCCESS = 0,            ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED = 1,//连接的实例ID与已有的ID重复或超过最大值            ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH,//连接的网络路径格式错误,无法检测出来目标IP离线等错误            ERRI_CONNECTION_COUNT_LIMIT_REACHED,//达到最大连接数量            ERRI_OUT_OF_MEMORY,//内存溢出,缓冲区已满            ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH, //连接的网络地址无效            ERRR_CONN_CONFIG_FAILED_NO_RESPONSE, //连接无响应            ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE,//连接响应错误            ERRR_INVALID_DESTINATION,  //目标标签不存在            ERRR_TAGNAME_TOO_LONG,  //标签名超过255字节            ERRR_REQUEST_DATA_TOO_LARGE,  //请求数据超限            ERRR_CONN_CONNECTION_TIMED_OUT, //活动连接响应超时,请检查目标IP是否离线            ERRR_TAGNAME_CONVERT_FAILED, //标签名解析错误            ERRR_WRITE_DATASIZE_UNCONSISTENT, //数据长度与标签实际长度不一致            ERRR_SCAN_ERROR, //扫描标签信息失败        };        public enum TAG_TYPE : int        {            TAG_TYPE_UNDEFINE = -1,            TAG_TYPE_BOOL = 0xC1, //新增            TAG_TYPE_SINT = 0xC2,            TAG_TYPE_INT = 0xC3,            TAG_TYPE_DINT = 0xC4,            TAG_TYPE_LINT = 0xC5,            TAG_TYPE_USINT = 0xC6,            TAG_TYPE_UINT = 0xC7,            TAG_TYPE_UDINT = 0xC8,            TAG_TYPE_ULINT = 0xC9,            TAG_TYPE_REAL = 0xCA,            TAG_TYPE_LREAL = 0xCB,            TAG_TYPE_STRING = 0xD0, //新增            TAG_TYPE_BYTE = 0xD1,            TAG_TYPE_WORD = 0xD2,            TAG_TYPE_DWORD = 0xD3,            TAG_TYPE_LWORD = 0xD4,            TAG_TYPE_STRUCT = 0xA2,  //新增            TAG_TYPE_ARRAY = 0xA3        };        enum EtIPConnectionState : int        {            ConnectionNonExistent = 0x0,    //该实例未有连接            ConnectionConfiguring = 0x1,    //连接正在打开过程中            ConnectionEstablished = 0x3,    //连接已成功建立并在活动中            ConnectionTimedOut = 0x4,       //连接超时            ConnectionClosing = 0x6         //连接正在关闭中        };        public const uint INVALID_MEMBER = 0xffffffff; //Member is not valid flag should be used when no member should be specified in the UCMM        public struct tagTagReadData        {            public string pName;            public int nElementCount;            public int nArrayPos;        };        public struct tagTagReadDataBase        {            public string pName;            public int nElementCount;        };        public struct tagTagRetValue        {            public IntPtr pData;            public TAG_TYPE pType;            public int nDataLength;            //tagTagRetValue()            //{            //    pData = NULL;            //    pType = TAG_TYPE_UNDEFINE;            //    nDataLength = 0;            //}            //~tagTagRetValue()            //{            //    if (pData)            //    {            //        delete pData;            //        pData = NULL;            //    }            //}        };        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]        public struct tagTagWriteData        {            public string pName;            public IntPtr pData;            public TAG_TYPE pType;            public int nArrayPos;            public int nDataLength;            public int nElementCount;        };        public struct tagTagWriteDataBase        {            public string pName;            public IntPtr pData;            public TAG_TYPE pType;            public int nDataLength;            public int nElementCount;        };        public class MySerializationBinder : SerializationBinder        {            public override Type BindToType(string assemblyName, string typeName)            {                // 如果类型名称是"MyNamespace.MyUnsupportedType",则将其转换为"MyNamespace.MySupportType"                if (typeName == "MyNamespace.MyUnsupportedType")                {                    return Type.GetType("MyNamespace.MySupportType");                }                // 否则返回null,表示无法进行转换                return null;            }        }        #endregion 自定义的结构        #region 动态类型        public class DynamicMethodProvider        {            public dynamic GetDynamicValue(string propertyName)            {                dynamic result;                switch (propertyName)                {                    case "Name":                        result = "John Doe";                        break;                    case "Age":                        result = 30;                        break;                    default:                        result = new ExpandoObject();                        ((IDictionary<string, object>)result).Add("UnknownProperty", "UnknownValue");                        break;                }                return result;            }        }        public static T CreateElement<T>()        {            Type t = typeof(T);            return (T)t.Assembly.CreateInstance(t.FullName);        }        public static dynamic CreateElement(string typename)        {            Type t = GetTypeByName(typename);            return t.Assembly.CreateInstance(t.FullName);        }              public static Type GetTypeByName(string typename)        {            Type t = null;            string source = typename;            try            {                t = Type.GetType(source);                if (t != null)                {                    return t;                }                Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();                foreach (Assembly ass in assembly)                {                    t = ass.GetType(source);                    if (t != null)                    {                        return t;                    }                    Type[] ts = ass.GetTypes();                    foreach (Type st in ts)                    {                        if (Regex.IsMatch(st.FullName, @"\." + source + @"(`?\d+)?$"))                        {                            return st;                        }                    }                }            }            catch (Exception ex)            {            }            return t;        }              public static Type GetTypeByName2(string typename)        {            Type t = null;            string source = typename;            if (source.IndexOf('<') > 0)            {                List<string> lv = new List<string>();                while (Regex.IsMatch(source, @"<[^<>]+>"))                {                    lv.Add(Regex.Match(source, @"(?<=<)[^<>]+(?=>)").Value);                    source = Regex.Replace(source, @"<[^<>]+>", "/" + (lv.Count - 1));                }                List<Type[]> args = new List<Type[]>();                for (int i = 0; i < lv.Count; i++)                {                    List<Type> arg = new List<Type>();                    string[] sp = lv[i].Split(',');                    for (int j = 0; j < sp.Length; j++)                    {                        string s = sp[j].Trim();                        if (!string.IsNullOrEmpty(s))                        {                            if (Regex.IsMatch(s, @"/\d+$"))                            {                                Match m = Regex.Match(s, @"^([^/\s]+)\s*/(\d+)$");                                if (!m.Success)                                {                                    throw new Exception("");                                }                                Type p = GetTypeByName(m.Groups[1].Value);                                Type c = p.MakeGenericType(args[Convert.ToInt32(m.Groups[2].Value)]);                                arg.Add(c);                            }                            else                            {                                arg.Add(GetTypeByName(s));                            }                        }                    }                    args.Add(arg.ToArray());                }                Match f = Regex.Match(source, @"^([^/\s]+)\s*/(\d+)$");                if (!f.Success)                {                    throw new Exception("");                }                Type fp = GetTypeByName(f.Groups[1].Value);                Type fc = fp.MakeGenericType(args[Convert.ToInt32(f.Groups[2].Value)]);                return fc;            }            else            {                try                {                    t = Type.GetType(source);                    if (t != null)                    {                        return t;                    }                    Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();                    foreach (Assembly ass in assembly)                    {                        t = ass.GetType(source);                        if (t != null)                        {                            return t;                        }                        Type[] ts = ass.GetTypes();                        foreach (Type st in ts)                        {                            //if (Regex.IsMatch(st.FullName, @"\." + Regex.FormatRegEx(source) + @"(`?\d+)?$"))                            if (Regex.IsMatch(st.FullName, @"\." + source + @"(`?\d+)?$"))                            {                                return st;                            }                        }                    }                }                catch (Exception ex)                {                }            }            return t;        }        #endregion 动态类型        #region DLL        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern void EipStart();        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern void EipStop();        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipOpenConnection(string ipAddress, IntPtr instanceID);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipCloseConnection(int nID);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipReadTag(int instanceID, string tagName, IntPtr type, byte[] dest, int dataLength, ushort elementCount = 1, uint nPos = INVALID_MEMBER);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipWriteTag(int instanceID, string tagName, int type, byte[] source, int dataLength, ushort elementCount = 1, uint nPos = INVALID_MEMBER/*, uint strLen = 0*/);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipGetConnectionState(int nID);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern bool EipStartExt(string ipAddress, uint nPort = 0);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipReadTagList(int instanceID, int nNumOfTags, tagTagReadData[] pTagList, ref tagTagRetValue pdest);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern ERROR_NO EipWriteTagList(int instanceID, int nNumOfTags, tagTagWriteData[] pTagWritenData);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern bool DeleteTagListStru(ref tagTagRetValue pRetValue, int nNumOfTags);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipReadTagExt(int instanceID, string tagName, IntPtr type, byte[] dest, int dataLength, ushort elementCount = 1);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipWriteTagExt(int instanceID, string tagName, int type, byte[] source, int dataLength, ushort elementCount = 1);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipReadTagListExt(int instanceID, int nNumOfTags, tagTagReadDataBase[] pTagList, ref tagTagRetValue pdest, bool bScan = false);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern ERROR_NO EipWriteTagListExt(int instanceID, int nNumOfTags, tagTagWriteDataBase[] pTagWritenData, bool bScan = false);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern ERROR_NO EipReadTagExt2(int iInstanceID, tagTagReadDataBase[] pTagList, ref tagTagRetValue pDest);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern ERROR_NO EipWriteTagExt2(int iInstanceID, tagTagWriteDataBase[] pTagWritenData);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern void ResetTagInfo();        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern ERROR_NO EipReadTagRaw(int iInstanceID, tagTagReadDataBase[] pTagList, ref tagTagRetValue pDest);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern ERROR_NO EipWriteTagRaw(int iInstanceID, tagTagWriteDataBase[] pTagWritenData);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern int EipReadTagListRaw(int instanceID, int nNumOfTags, tagTagReadDataBase[] pTagList, ref tagTagRetValue pdest);        [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]        public static extern ERROR_NO EipWriteTagListRaw(int instanceID, int nNumOfTags, tagTagWriteDataBase[] pTagWritenData);        #endregion DLL        #region private方法        private string getTypeString(TAG_TYPE eType)        {            string strType = "";            switch (eType)            {                case TAG_TYPE.TAG_TYPE_SINT:                    strType = "SINT";                    break;                case TAG_TYPE.TAG_TYPE_INT:                    strType = "INT";                    break;                case TAG_TYPE.TAG_TYPE_DINT:                    strType = "DINT";                    break;                case TAG_TYPE.TAG_TYPE_LINT:                    strType = "LINT";                    break;                case TAG_TYPE.TAG_TYPE_USINT:                    strType = "USINT";                    break;                case TAG_TYPE.TAG_TYPE_UINT:                    strType = "UINT";                    break;                case TAG_TYPE.TAG_TYPE_UDINT:                    strType = "UDINT";                    break;                case TAG_TYPE.TAG_TYPE_ULINT:                    strType = "ULINT";                    break;                case TAG_TYPE.TAG_TYPE_REAL:                    strType = "REAL";                    break;                case TAG_TYPE.TAG_TYPE_LREAL:                    strType = "LREAL";                    break;                case TAG_TYPE.TAG_TYPE_BYTE:                    strType = "BYTE";                    break;                case TAG_TYPE.TAG_TYPE_WORD:                    strType = "WORD";                    break;                case TAG_TYPE.TAG_TYPE_DWORD:                    strType = "DWORD";                    break;                case TAG_TYPE.TAG_TYPE_LWORD:                    strType = "LWORD";                    break;                case TAG_TYPE.TAG_TYPE_BOOL:                    strType = "BOOL";                    break;                case TAG_TYPE.TAG_TYPE_STRING:                    strType = "STRING";                    break;                case TAG_TYPE.TAG_TYPE_STRUCT:                    strType = "STRUCT";                    break;                default:                    break;            }            return strType;        }        private byte[] StringToBytes(string s)        {            string[] str = s.Split(' ');            int n = str.Length;            byte[] cmdBytes = null;            int p = 0;            for (int k = 0; k < n; k++)            {                int sLen = str[k].Length;                int bytesLen = sLen / 2;                int position = 0;                byte[] bytes = new byte[bytesLen];                for (int i = 0; i < bytesLen; i++)                {                    string abyte = str[k].Substring(position, 2);                    bytes[i] = Convert.ToByte(abyte, 16);                    position += 2;                }                if (position >= 2)                {                    byte[] cmdBytes2 = new byte[p + bytesLen];                    if (cmdBytes != null)                    {                        Array.Copy(cmdBytes, 0, cmdBytes2, 0, p);                    }                    Array.Copy(bytes, 0, cmdBytes2, p, bytesLen);                    cmdBytes = cmdBytes2;                    p += bytesLen;                }            }            return cmdBytes;        }        private (int,string) OpenEip(string strLocalComputerIp)        {            //limit input of controller            bool blnTest = false;            bool bValidIP = true;            Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");            blnTest = regex.IsMatch(strLocalComputerIp);            if (blnTest == true)            {                string[] strTemp = strLocalComputerIp.Split(new char[] { '.' });                if (strTemp.Length < 4)                {                    bValidIP = false;                    return (-1, "不符合IP格式");                }                for (int i = 0; (i < strTemp.Length) && bValidIP; i++)                {                    if (Convert.ToInt32(strTemp[i]) > 255)                    {                         //大于255则提示,不符合IP格式                        bValidIP = false;                        return (-2, "IP大于255,不符合IP格式");                    }                }            }            else            {                //输入非数字则提示,不符合IP格式                bValidIP = false;                return (-3, "输入非数字,不符合IP格式");            }            if (bValidIP)            {                if (!isStart)                {                    if (EipStartExt(strLocalComputerIp, 0))                    {                        isStart = true;                        strClaimedComputerIP = strLocalComputerIp;                        return (0, "EIP协议栈开启成功");                    }                    else                    {                        isStart = false;                        return (1, "EIP协议栈开启失败");                    }                 }                else                {                    if (string.Compare(strClaimedComputerIP, strLocalComputerIp) != 0)                    {                        return (2,"更改上位机IP时需先关闭协议栈,再开启");                    }                    else                    {                        return (3, "EIP协议栈已经开启");                    }                }            }            return (-4, "无效IP");        }        private (bool,string) CloseEip()        {            if (isStart)            {                EipStop();                isStart = false;                return (true, "EIP协议栈关闭");            }            else            {                return (false, "EIP协议栈未开启,请先开启");            }        }        #endregion private方法        #region 连接/断开        #region 连接方式 一        public Inovance_EIP() { }        /// <summary>        /// 连接PLC        /// </summary>        /// <param name="strComputerIp">PC的IP地址</param>        /// <param name="strPlcIp">PLC的IP地址</param>        /// <returns>成功:True  失败:False </returns>        public (int,string) Connect(string strComputerIp,string strPlcIp)        {            _pcIPStr = strComputerIp;            _plcIPStr = strPlcIp;            lock (m_objLock)            {                string strRet = "";                int nRet = 0;                if (!isStart) (nRet, strRet) = OpenEip(strComputerIp);                if (nRet != 0) return (nRet, strRet);                bool blnTest = false;                bool bValidIP = true;                Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");                blnTest = regex.IsMatch(strPlcIp);                if (blnTest == true)                {                    string[] strTemp = strPlcIp.Split(new char[] { '.' });                    for (int i = 0; i < strTemp.Length; i++)                    {                        if (Convert.ToInt32(strTemp[i]) > 255)                        {                            bValidIP = false;                            return (-10, "PLC IP 大于255,不符合IP格式");                        }                    }                }                else                {                    bValidIP = false;                    return (-11, "PLC IP输入非数字,不符合IP格式");                }                if (bValidIP)                {                    if (strPlcIp.CompareTo(strClaimedComputerIP) == 0)                    {                        string strLog = "";                        strLog += "上位机IP与PLC IP相同,请重新输入";                        return (-20, strLog);                    }                    if (strPlcIp.CompareTo(strComputerIp) == 0)                    {                        string strLog = "";                        strLog += "上位机IP与PLC IP相同,请重新输入";                        return (-21, strLog);                    }                    int instanceId = 0;                    ERROR_NO errorNo;                    unsafe                    {                        errorNo = (ERROR_NO)EipOpenConnection(strPlcIp, (IntPtr)(&instanceId));                    }                    m_nInstanceId = instanceId;                    string str = "";                    str += "\n请求创建PLC连接 ip:";                    str += strPlcIp;                    str += " ";                    if (errorNo != ERROR_NO.SUCCESS)                    {                        m_bConnected = false;                        str += ("失败 ");                        switch (errorNo)                        {                            case ERROR_NO.ERR_EIP_STOPED:                                str += ("协议栈未开启");                                break;                            case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:                                str += ("连接的实例ID与已有的ID重复或超过最大值");                                break;                            case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                                str += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");                                break;                            case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:                                str += ("达到最大连接数量");                                break;                            case ERROR_NO.ERRI_OUT_OF_MEMORY:                                str += ("内存溢出,缓冲区已满");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                                str += ("连接的网络地址无效");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:                                str += ("连接无响应");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:                                str += ("连接响应错误");                                break;                            default:                                str += ("其他错误");                                break;                        }                    }                    else                    {                        str += "成功";                        str += " 分配的实例ID 为 ";                        str += instanceId.ToString();                        m_bConnected = true;                        return (0, str);                    }                    str += "\n";                    return (100 + (int)errorNo, str);                }            }            return (1000, "Error");        }        #endregion 连接方式 一        #region 连接方式 二        /// <summary>        ///         /// </summary>        /// <param name="strComputerIp">PC的IP地址</param>        /// <param name="strPlcIp">PLC的IP地址</param>        public Inovance_EIP(string strComputerIp, string strPlcIp)        {            _pcIPStr = strComputerIp;            _plcIPStr = strPlcIp;        }        /// <summary>        /// 连接PLC        /// </summary>        /// <returns>成功:True  失败:False </returns>        public (int, string) Connect()        {            lock (m_objLock)            {                string strRet = "";                int nRet = 0;                if (!isStart) (nRet, strRet) = OpenEip(_pcIPStr);                if (nRet != 0) return (nRet, strRet);                bool blnTest = false;                bool bValidIP = true;                Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");                blnTest = regex.IsMatch(_plcIPStr);                if (blnTest == true)                {                    string[] strTemp = _plcIPStr.Split(new char[] { '.' });                    for (int i = 0; i < strTemp.Length; i++)                    {                        if (Convert.ToInt32(strTemp[i]) > 255)                        {                            bValidIP = false;                            return (-10, "PLC IP 大于255,不符合IP格式");                        }                    }                }                else                {                    bValidIP = false;                    return (-11, "PLC IP输入非数字,不符合IP格式");                }                if (bValidIP)                {                    if (_plcIPStr.CompareTo(strClaimedComputerIP) == 0)                    {                        string strLog = "";                        strLog += "上位机IP与PLC IP相同,请重新输入";                        return (-20, strLog);                    }                    if (_plcIPStr.CompareTo(_pcIPStr) == 0)                    {                        string strLog = "";                        strLog += "上位机IP与PLC IP相同,请重新输入";                        return (-21, strLog);                    }                    int instanceId = 0;                    ERROR_NO errorNo;                    unsafe                    {                        errorNo = (ERROR_NO)EipOpenConnection(_plcIPStr, (IntPtr)(&instanceId));                    }                    m_nInstanceId = instanceId;                    string str = "";                    str += "\n请求创建PLC连接 ip:";                    str += _plcIPStr;                    str += " ";                    if (errorNo != ERROR_NO.SUCCESS)                    {                        m_bConnected = false;                        str += ("失败 ");                        switch (errorNo)                        {                            case ERROR_NO.ERR_EIP_STOPED:                                str += ("协议栈未开启");                                break;                            case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:                                str += ("连接的实例ID与已有的ID重复或超过最大值");                                break;                            case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                                str += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");                                break;                            case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:                                str += ("达到最大连接数量");                                break;                            case ERROR_NO.ERRI_OUT_OF_MEMORY:                                str += ("内存溢出,缓冲区已满");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                                str += ("连接的网络地址无效");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:                                str += ("连接无响应");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:                                str += ("连接响应错误");                                break;                            default:                                str += ("其他错误");                                break;                        }                    }                    else                    {                        str += "成功";                        str += " 分配的实例ID 为 ";                        str += instanceId.ToString();                        m_bConnected = true;                        return (0, str);                    }                    str += "\n";                    return (100 + (int)errorNo, str);                }            }            return (1000, "Error");        }        #endregion 连接方式 二        /// <summary>        /// 断开连接        /// </summary>        /// <returns>成功:True  失败:False</returns>        public bool Disconnect()        {            lock (m_objLock)            {                if (m_nInstanceId == 0 || !m_bConnected)                {                    m_nInstanceId = 0;                    m_bConnected = false;                    return true;                }                ERROR_NO errorNo = (ERROR_NO)EipCloseConnection(m_nInstanceId);                //string str = "";                if (errorNo != ERROR_NO.SUCCESS)                {                    //str += "失败";                    m_bConnected = false;                    m_nInstanceId = 0;                    return false;                }                else                {                    //str += "成功";                    m_bConnected = false;                    m_nInstanceId = 0;                    CloseEip();                    return true;                }            }        }        #endregion 连接/断开        public (int,string) Read_Tag(string strTagName, int nCount, out byte[] pBuf)        {            pBuf = null;            string strType = "";            lock (m_objLock)            {                if (!m_bConnected) return (-1,"未连接");                string tagName = strTagName;                byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(tagName);                if (m_nInstanceId <= 0)                {                    return (-2, "实例ID需大于0");                }                if (tagNameUTF8.Length > 255)                {                    return (-3, "标签名长度超过255字节");                }                ushort elementCount = (ushort)nCount;                if (elementCount > 0)                {                    int destLength = 1400;                    byte[] dest = new byte[destLength];                    char[] cChar = Encoding.ASCII.GetChars(dest);                    //TAG_TYPE type = TAG_TYPE.TAG_TYPE_UNDEFINE;                    //int returnLength = 0;                    tagTagReadDataBase[] pTaglist = new tagTagReadDataBase[1];                    pTaglist[0].pName = tagName;                    pTaglist[0].nElementCount = elementCount;                    tagTagRetValue[] tagValue = new tagTagRetValue[1];                    ERROR_NO errorNo = ERROR_NO.OTHER_ERROR;                    unsafe                    {                        errorNo = EipReadTagExt2(m_nInstanceId, pTaglist, ref tagValue[0]);                    }                    string strLog = "";                    strLog += "读取请求";                    if (/*returnLength < 0*/errorNo != ERROR_NO.SUCCESS)                    {                        strLog += " 失败 标签名:" + tagName + " 实例ID:" + m_nInstanceId.ToString() + " ";                        switch (/*returnLength*/errorNo)                        {                            //case -1:                            //    strLog += ("其他错误");                            //    break;                            //case -2:                            //    strLog += ("协议栈未开启");                            //    break;                            //case -3:                            //    strLog += ("实例id小于或等于0");                            //    break;                            //case -4:                            //    strLog += ("标签名长度大于255字节");                            //    break;                            //case -5:                            //    strLog += ("目标标签不存在");                            //    break;                            //case -6:                            //    strLog += ("响应超时,请检查设备是否离线");                            //    break;                            //case -7:                            //    strLog += ("标签名解析错误");                            //    break;                            //case -8:                            //    strLog += ("扫描标签信息失败");                            //    break;                            //default:                            //    strLog += ("其他错误");                            //    break;                            case ERROR_NO.ERR_EIP_STOPED:                                strLog += ("协议栈未开启");                                break;                            case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:                                strLog += ("连接的实例ID与已有的ID重复或超过最大值");                                break;                            case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                                strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");                                break;                            case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:                                strLog += ("达到最大连接数量");                                break;                            case ERROR_NO.ERRI_OUT_OF_MEMORY:                                strLog += ("内存溢出,缓冲区已满");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                                strLog += ("连接的网络地址无效");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:                                strLog += ("连接无响应");                                break;                            case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:                                strLog += ("连接响应错误");                                break;                            case ERROR_NO.ERRR_INVALID_DESTINATION:                                strLog += ("目标标签不存在");                                break;                            case ERROR_NO.ERRR_TAGNAME_TOO_LONG:                                strLog += ("标签名超过255字节");                                break;                            case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:                                strLog += ("请求数据超限");                                break;                            case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:                                strLog += ("响应超时,请检查设备是否离线");                                break;                            case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:                                strLog += ("标签名解析错误");                                break;                            case ERROR_NO.ERRR_SCAN_ERROR:                                strLog += ("扫描标签信息失败");                                break;                            default:                                strLog += ("其他错误");                                break;                        }                        strLog += "\n";                        return (10,strLog);                    }                    else                    {                        switch (/*type*/tagValue[0].pType)                        {                            case TAG_TYPE.TAG_TYPE_BOOL:                                strType += "Boolean";                                   break;                            case TAG_TYPE.TAG_TYPE_SINT:                                strType += "SByte";                                break;                            case TAG_TYPE.TAG_TYPE_INT:                                strType += "Int16";                                break;                            case TAG_TYPE.TAG_TYPE_DINT:                                strType += "Int32";                                break;                            case TAG_TYPE.TAG_TYPE_LINT:                                strType += "Int64";                                break;                            case TAG_TYPE.TAG_TYPE_USINT:                                strType += "Byte";                                break;                            case TAG_TYPE.TAG_TYPE_UINT:                                strType += "UInt16";                                break;                            case TAG_TYPE.TAG_TYPE_UDINT:                                strType += "UInt32";                                break;                            case TAG_TYPE.TAG_TYPE_ULINT:                                strType += "UInt64";                                break;                            case TAG_TYPE.TAG_TYPE_REAL:                                strType += "Single";                                break;                            case TAG_TYPE.TAG_TYPE_LREAL:                                strType += "Double";                                break;                            case TAG_TYPE.TAG_TYPE_STRING:                                strType += "String";                                break;                            case TAG_TYPE.TAG_TYPE_BYTE:                                strType += "Byte";                                break;                            case TAG_TYPE.TAG_TYPE_WORD:                                strType += "UInt16";                                break;                            case TAG_TYPE.TAG_TYPE_DWORD:                                strType += "UInt32";                                break;                            case TAG_TYPE.TAG_TYPE_LWORD:                                strType += "UInt64";                                break;                            case TAG_TYPE.TAG_TYPE_STRUCT:                                strType += "STRUCT";                                break;                            case TAG_TYPE.TAG_TYPE_ARRAY:                                strType += "ARRAY";                                break;                            default:                                break;                        }                                          pBuf = new byte[tagValue[0].nDataLength];                        unsafe                        {                            byte* memBytePtr = (byte*)tagValue[0].pData.ToPointer();                            for (int j = 0; j < tagValue[0].nDataLength; j++)                            {                                pBuf[j] = memBytePtr[j];                                //string str = "";                                //str += j.ToString() + ": ";                                //str += "0x" + String.Format("{0:X2}", memBytePtr[j]) + "\n";                            }                        }                        DeleteTagListStru(ref tagValue[0], 1); //调用接口释放内存                    }                }                else                {                    return (-10, "元素个数参数错误,必须>0");                }                return (0, strType);            }        }        public (int, string) Write_Tag(string strTagName, int nCount, byte[] pBuf)        {            lock (m_objLock)            {                if (!m_bConnected) return (-1, "未连接");                string tagName = strTagName;                byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(tagName);                if (m_nInstanceId <= 0)                {                    return (-2, "实例ID需大于0");                }                if (tagNameUTF8.Length > 255)                {                    return (-3, "标签名长度超过255字节");                }                ushort elementCount = (ushort)nCount;                if ((pBuf.Length < 1) || (elementCount < 1))                {                    return (-4, "请求个数必须大于0,请重新输入");                }                if (pBuf.Length > 1400)                {                    return (-5, "标签数据长度超过1400字节,请重新输入");                }                int dataLength = pBuf.Length;                tagTagWriteDataBase[] pTaglist = new tagTagWriteDataBase[1];                //标签1属性                pTaglist[0].pName = tagName;                pTaglist[0].nElementCount = elementCount;                pTaglist[0].pType = TAG_TYPE.TAG_TYPE_UNDEFINE;                pTaglist[0].pData = Marshal.AllocHGlobal(1400);                pTaglist[0].nDataLength = dataLength;                byte temp = 0;                for (int i = 0; i < dataLength; ++i)                {                    temp = pBuf[i];                    Marshal.WriteByte(pTaglist[0].pData + i * sizeof(byte), temp);                }                //ERROR_NO errorNo = (ERROR_NO)EipWriteTag(m_nInstanceId, tagName, (int)type, source, dataLength, elementCount, arrayPos/*, strLen*/);                //ERROR_NO errorNo = (ERROR_NO)EipWriteTagExt(m_nInstanceId, tagName, (int)type, source, dataLength, elementCount);                ERROR_NO errorNo = EipWriteTagExt2(m_nInstanceId, pTaglist);                //ERROR_NO errorNo = EipWriteTagRaw(instanceId, pTaglist);                string strLog = "";                strLog += "\n写入请求 ";                if (errorNo != ERROR_NO.SUCCESS)                {                    strLog += " 失败 标签名:" + tagName + " 实例ID:" + m_nInstanceId.ToString() + " ";                    switch (errorNo)                    {                        case ERROR_NO.ERR_EIP_STOPED:                            strLog += ("协议栈未开启");                            break;                        case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:                            strLog += ("连接的实例ID与已有的ID重复或超过最大值");                            break;                        case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                            strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");                            break;                        case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:                            strLog += ("达到最大连接数量");                            break;                        case ERROR_NO.ERRI_OUT_OF_MEMORY:                            strLog += ("内存溢出,缓冲区已满");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                            strLog += ("连接的网络地址无效");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:                            strLog += ("连接无响应");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:                            strLog += ("连接响应错误");                            break;                        case ERROR_NO.ERRR_INVALID_DESTINATION:                            strLog += ("目标标签不存在");                            break;                        case ERROR_NO.ERRR_TAGNAME_TOO_LONG:                            strLog += ("标签名超过255字节");                            break;                        case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:                            strLog += ("请求数据超限");                            break;                        case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:                            strLog += ("响应超时,请检查设备是否离线");                            break;                        case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:                            strLog += ("标签名解析错误");                            break;                        case ERROR_NO.ERRR_WRITE_DATASIZE_UNCONSISTENT:                            strLog += ("写入数据长度与标签实际长度不一致");                            break;                        case ERROR_NO.ERRR_SCAN_ERROR:                            strLog += ("扫描标签信息失败");                            break;                        default:                            strLog += ("其他错误");                            break;                    }                    strLog += "\n";                    return (10, strLog);                }                else                {                    return (0, "OK");                }            }        }        /// <summary>        /// 标签结构        /// </summary>        public struct StructTag        {            public string strTagName;            public Type tTagType;            public int nCount;        }                /// <summary>        /// 一次读取多个标签        /// </summary>        /// <param name="stTagList">多个标签的列表</param>        /// <param name="pBuf">多个标签的返回值</param>        /// <returns>函数执行结构值,非零异常,零成功</returns>        public (int, string) Read_Tags(List<StructTag> stTagList, out byte[][] pBuf)        {            pBuf = null;            string strType = "";            lock (m_objLock)            {                if (!m_bConnected) return (-1, "未连接");                if (m_nInstanceId <= 0)                {                    return (-2, "实例ID需大于0");                }                if (stTagList == null) return (-3, "标签列表空");                int nNumOfTags = stTagList.Count;                if (nNumOfTags < 1) return (-4, "标签列表长度空");                for (int i = 0; i < nNumOfTags; i++)                {                    byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(stTagList[i].strTagName);                    if (tagNameUTF8.Length > 255)                    {                        return (-5, "标签名长度超过255字节");                    }                    if (stTagList[i].nCount < 1) return (-6, "标签读取长度小于1");                }                tagTagReadDataBase[] pTaglist = new tagTagReadDataBase[nNumOfTags];                for (int i = 0; i < nNumOfTags; i++)                {                    pTaglist[i].pName = stTagList[i].strTagName;                    pTaglist[i].nElementCount = stTagList[i].nCount;                }                tagTagRetValue[] pTagsValue = new tagTagRetValue[nNumOfTags];                pBuf = new byte[nNumOfTags][];                if (pBuf == null) return (-7, "分配内存失败,可能内存不足");                //ERROR_NO errorNo = (ERROR_NO)EipReadTagList(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0]);                ERROR_NO errorNo = (ERROR_NO)EipReadTagListExt(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0], true);                //ERROR_NO errorNo = (ERROR_NO)EipReadTagListRaw(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0]);                string strLog = "";                strLog += "\n读取请求";                if (errorNo != ERROR_NO.SUCCESS)                {                    strLog += " 失败 标签个数:" + nNumOfTags.ToString() + " 实例ID:" + m_nInstanceId.ToString() + " ";                    switch (errorNo)                    {                        case ERROR_NO.ERR_EIP_STOPED:                            strLog += ("协议栈未开启");                            break;                        case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:                            strLog += ("连接的实例ID与已有的ID重复或超过最大值");                            break;                        case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                            strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");                            break;                        case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:                            strLog += ("达到最大连接数量");                            break;                        case ERROR_NO.ERRI_OUT_OF_MEMORY:                            strLog += ("内存溢出,缓冲区已满");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                            strLog += ("连接的网络地址无效");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:                            strLog += ("连接无响应");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:                            strLog += ("连接响应错误");                            break;                        case ERROR_NO.ERRR_INVALID_DESTINATION:                            strLog += ("目标标签不存在");                            break;                        case ERROR_NO.ERRR_TAGNAME_TOO_LONG:                            strLog += ("标签名超过255字节");                            break;                        case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:                            strLog += ("请求数据超限");                            break;                        case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:                            strLog += ("响应超时,请检查设备是否离线");                            break;                        case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:                            strLog += ("标签名解析错误");                            break;                        case ERROR_NO.ERRR_SCAN_ERROR:                            strLog += ("扫描标签信息失败");                            break;                        default:                            strLog += ("其他错误");                            break;                    }                    strLog += "\n";                    return (-10, strLog);                }                else                {                    for (int i = 0; i < nNumOfTags; i++)                    {                        strType += "\n标签名:" + pTaglist[i].pName + " 类型:";                        switch (pTagsValue[i].pType)                        {                            case TAG_TYPE.TAG_TYPE_BOOL:                                strType += "BOOL";                                break;                            case TAG_TYPE.TAG_TYPE_SINT:                                strType += "SINT";                                break;                            case TAG_TYPE.TAG_TYPE_INT:                                strType += "INT";                                break;                            case TAG_TYPE.TAG_TYPE_DINT:                                strType += "DINT";                                break;                            case TAG_TYPE.TAG_TYPE_LINT:                                strType += "LINT";                                break;                            case TAG_TYPE.TAG_TYPE_USINT:                                strType += "USINT";                                break;                            case TAG_TYPE.TAG_TYPE_UINT:                                strType += "UINT";                                break;                            case TAG_TYPE.TAG_TYPE_UDINT:                                strType += "UDINT";                                break;                            case TAG_TYPE.TAG_TYPE_ULINT:                                strType += "ULINT";                                break;                            case TAG_TYPE.TAG_TYPE_REAL:                                strType += "REAL";                                break;                            case TAG_TYPE.TAG_TYPE_LREAL:                                strType += "LREAL";                                break;                            case TAG_TYPE.TAG_TYPE_STRING:                                strType += "STRING";                                break;                            case TAG_TYPE.TAG_TYPE_BYTE:                                strType += "BYTE";                                break;                            case TAG_TYPE.TAG_TYPE_WORD:                                strType += "WORD";                                break;                            case TAG_TYPE.TAG_TYPE_DWORD:                                strType += "DWORD";                                break;                            case TAG_TYPE.TAG_TYPE_LWORD:                                strType += "LWORD";                                break;                            case TAG_TYPE.TAG_TYPE_STRUCT:                                strType += "STRUCT";                                break;                            case TAG_TYPE.TAG_TYPE_ARRAY:                                strType += "ARRAY";                                break;                            default:                                strType += pTagsValue[i].pType.ToString();                                break;                        }                        strType += " 元素个数:" + pTaglist[i].nElementCount.ToString();                        strType += " 数据长度:" + pTagsValue[i].nDataLength.ToString() + "\n";                        unsafe                        {                            byte* memBytePtr = (byte*)pTagsValue[i].pData.ToPointer();                            pBuf[i] = new byte[pTagsValue[i].nDataLength];                            for (int j = 0; j < pTagsValue[i].nDataLength; j++)                            {                                pBuf[i][j] = memBytePtr[j];                                //string str = "";                                ///str += j.ToString() + ": ";                                //str += "0x" + String.Format("{0:X2}", memBytePtr[j]) + "\n";                             }                        }                    }                }                DeleteTagListStru(ref pTagsValue[0], nNumOfTags); //调用接口释放内存                return (0, strType);            }        }        /// <summary>        /// 一次写多个标签        /// </summary>        /// <param name="TagList">将写入的标签列表</param>        /// <param name="ObjList">与标签列表对应的值对象</param>        /// <returns></returns>        public (int, string) Write_Tags(List<StructTag> TagList, List<Object> ObjList)        {            int size = 0;            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            if (!m_bConnected) return (-1, "未连接");            if (m_nInstanceId <= 0) return (-2, "实例ID需大于0");            if (ObjList.Count != TagList.Count) return (-3, "标签列表和数据列表不一致");            int nLen = TagList.Count;            int nNumOfTags = TagList.Count;            tagTagWriteDataBase[] pTaglist = new tagTagWriteDataBase[nNumOfTags];            try            {                for (int i = 0; i < nLen; i++)                {                    if (TagList[i].strTagName.Length > 255) return (-4, "标签名称长度超过255字节");                    if (TagList[i].tTagType == null) return (-5, "标签类型不能空");                    //标签属性                    pTaglist[i].pName = TagList[i].strTagName;                    pTaglist[i].nElementCount = TagList[i].nCount;                    pTaglist[i].pType = TAG_TYPE.TAG_TYPE_UNDEFINE;                    pTaglist[i].pData = Marshal.AllocHGlobal(1400);                    //标签写入的数据                    size = 0;                    string str = TagList[i].tTagType.Name;                    string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };                    bool containsAny = substrings.Any(substring => str.Contains(substring));                    if (containsAny)                    {                        Type type = ObjList[i].GetType();                        if (str != type.Name) return (120, "变量类型不一致");                    }                    if (str == "String")                    {                        string data = ObjList[i] as string;                        pBuf = System.Text.Encoding.Default.GetBytes(data);                        size = pBuf.Length;                        if (size > 1400)                        {                            return (110, "数据长度超过1400字节,请重新输入");                        }                    }                    else                    {                        if (TagList[i].tTagType.Name == "Boolean")                        {                            pBuf = new byte[1];                            Type targetType = TagList[i].tTagType;                            if ((bool)Convert.ChangeType(ObjList[i], targetType))                            {                                pBuf[0] = 1;                            }                            else                            {                                pBuf[0] = 0;                            }                            size = 1;                        }                        else                        {                            size = Marshal.SizeOf(TagList[i].tTagType);                            pBuf = StructToBytes(ObjList[i], size);                        }                    }                    //填充数据                    for (int j = 0; j < size; j++)                    {                        Marshal.WriteByte(pTaglist[i].pData + j * sizeof(byte), pBuf[j]);                    }                    pTaglist[i].nDataLength = size;                }                ERROR_NO errorNo = ERROR_NO.SUCCESS;                lock (m_objLock)                {                    //errorNo = EipWriteTagList(m_nInstanceId, nNumOfTags, pTaglist);                    errorNo = EipWriteTagListExt(m_nInstanceId, nNumOfTags, pTaglist, true);                    //errorNo = EipWriteTagListRaw(m_nInstanceId, nNumOfTags, pTaglist);                }                string strLog = "";                strLog += "\n写入请求";                if (errorNo != ERROR_NO.SUCCESS)                {                    strLog += " 失败 标签个数:" + nNumOfTags.ToString() + " 实例ID:" + m_nInstanceId.ToString() + " ";                    switch (errorNo)                    {                        case ERROR_NO.ERR_EIP_STOPED:                            strLog += ("协议栈未开启");                            break;                        case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:                            strLog += ("连接的实例ID与已有的ID重复或超过最大值");                            break;                        case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                            strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");                            break;                        case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:                            strLog += ("达到最大连接数量");                            break;                        case ERROR_NO.ERRI_OUT_OF_MEMORY:                            strLog += ("内存溢出,缓冲区已满");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:                            strLog += ("连接的网络地址无效");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:                            strLog += ("连接无响应");                            break;                        case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:                            strLog += ("连接响应错误");                            break;                        case ERROR_NO.ERRR_INVALID_DESTINATION:                            strLog += ("目标标签不存在");                            break;                        case ERROR_NO.ERRR_TAGNAME_TOO_LONG:                            strLog += ("标签名超过255字节");                            break;                        case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:                            strLog += ("请求数据超限");                            break;                        case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:                            strLog += ("响应超时,请检查设备是否离线");                            break;                        case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:                            strLog += ("标签名解析错误");                            break;                        case ERROR_NO.ERRR_WRITE_DATASIZE_UNCONSISTENT:                            strLog += ("写入数据长度与标签实际长度不一致");                            break;                        case ERROR_NO.ERRR_SCAN_ERROR:                            strLog += ("扫描标签信息失败");                            break;                        default:                            strLog += ("其他错误");                            break;                    }                    strLog += "\n";                    strRet = strLog;                    nRet = -10;                }                else                {                    //成功                    strRet = "OK";                    nRet = 0;                }            }            catch (Exception ex)            {                nRet = 120;                strRet = ex.ToString();            }            finally            {                for (int i = 0; i < nLen; i++)                {                    if (pTaglist[i].pData != ((IntPtr)0))                    {                        Marshal.FreeHGlobal(pTaglist[i].pData);                        pTaglist[i].pData = (IntPtr)0;                    }                }            }            return (nRet, strRet);        }        /// <summary>        /// 一次读取Bool标签或Bool数组标签        /// </summary>        /// <param name="strTagName">标签的名称</param>        /// <param name="nCount">读取的标签个数</param>        /// <param name="boolBuf">相应标签的返回值</param>        /// <returns>函数返回结果</returns>        public (int, string) Read_Bool_Tag(string strTagName, int nCount, out bool[] boolBuf)        {            byte[] pBuf = null;            boolBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_Bool_Tag(pBuf, out boolBuf);        }        /// <summary>        /// 一次写入Bool标签或Bool数组标签        /// </summary>        /// <param name="strTagName">标签的名称</param>        /// <param name="nCount">标签个数</param>        /// <param name="boolBuf">相应标签的写入值</param>        /// <returns>函数返回结果</returns>        public (int, string) Write_Bool_Tag(string strTagName, int nCount, bool[] boolBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = BoolToBytes(boolBuf);            if (pBuf == null) return (1, "缓存区空");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] BoolToBytes(bool[] boolBuf)        {            if (boolBuf==null) return null;            int nNum = 0;            nNum = boolBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum];            for (int i = 0; i < nNum; i++)            {                if (boolBuf[i])                    bytes[i] = 1;                else                    bytes[i] = 0;            }            return bytes;        }        public (int, string) Parse_Bool_Tag(byte[] pBuf, out bool[] boolBuf)        {            boolBuf = null;            int nNum = 0;            nNum = pBuf.Length;            if (nNum < 1) return (1, "Parse Failed");            boolBuf = new bool[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[1] {0};                databuf[0] = pBuf[i];                bool iTemp = BitConverter.ToBoolean(databuf, 0);                boolBuf[i] = iTemp;            }            return (0, "OK");        }        public (int, string) Read_Byte_Tag(string strTagName, int nCount, out byte[] pBuf)        {            return Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);        }        public (int, string) Write_Byte_Tag(string strTagName, int nCount, byte[] pBuf)        {            return Write_Tag(strTagPrefix + strTagName, nCount, pBuf);        }        public (int, string) Read_SInt_Tag(string strTagName, int nCount, out sbyte[] sintBuf)        {            byte[] pBuf = null;            sintBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_SInt_Tag(pBuf, out sintBuf);        }        public (int, string) Write_SInt_Tag(string strTagName, int nCount, sbyte[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = SByteToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] SByteToBytes(sbyte[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i] = databuf[0];            }            return bytes;        }        public (int, string) Parse_SInt_Tag(byte[] pBuf, out sbyte[] sintBuf)        {            sintBuf = null;            int nNum = 0;            nNum = pBuf.Length;            if (nNum < 1) return (1, "Parse Failed");            sintBuf = new sbyte[nNum];            for (int i = 0; i < nNum; i++)            {                sintBuf[i] = (sbyte)pBuf[i];            }            return (0, "OK");        }        public (int, string) Read_String_Tag(string strTagName, int nCount, out string strBuf)        {            int nRet=0;            string strRet = "";            byte[] pBuf = null;            strBuf = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet == 0)                strBuf = System.Text.Encoding.UTF8.GetString(pBuf);            return (nRet, strRet);        }        public (int, string) Write_String_Tag(string strTagName, int nCount, string strBuf)        {            int nRet = 0;            string strRet = "";            byte[] pBuf = null;            if (string.IsNullOrEmpty(strBuf)) return (1, "string is null");            pBuf = System.Text.Encoding.UTF8.GetBytes(strBuf);            if (pBuf == null || pBuf.Length == 0 ) return (2, "pBuf is null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        public (int, string) Parse_String_Tag(byte[] pBuf, out string strBuf)        {            int nRet = 0;            string strRet = "";            strBuf = "";            strBuf = System.Text.Encoding.UTF8.GetString(pBuf);            return (nRet, strRet);        }        public (int, string) Read_Word_Tag(string strTagName, int nCount, out ushort[] wordBuf)        {            return Read_UInt_Tag(strTagName, nCount, out wordBuf);        }        public (int, string) Write_Word_Tag(string strTagName, int nCount, ushort[] wordBuf)        {            return Write_UInt_Tag(strTagName, nCount, wordBuf);        }        public (int, string) Read_DWord_Tag(string strTagName, int nCount, out uint[] dwordBuf)        {            return Read_UDInt_Tag(strTagName, nCount, out dwordBuf);        }        public (int, string) Write_DWord_Tag(string strTagName, int nCount, uint[] dwordBuf)        {            return Write_UDInt_Tag(strTagName, nCount, dwordBuf);        }        public (int, string) Read_LWord_Tag(string strTagName, int nCount, out ulong[] lwordBuf)        {            return Read_ULInt_Tag(strTagName, nCount, out lwordBuf);        }        public (int, string) Write_LWord_Tag(string strTagName, int nCount, ulong[] lwordBuf)        {            return Write_ULInt_Tag(strTagName, nCount, lwordBuf);        }        /// <summary>        /// read 16bit int        /// </summary>        /// <param name="strTagName"></param>        /// <param name="nCount"></param>        /// <param name="intBuf"></param>        /// <returns></returns>        public (int, string) Read_Int_Tag(string strTagName, int nCount, out short[] intBuf)        {            byte[] pBuf = null;            intBuf = null;            int nRet=0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_Int_Tag(pBuf, out intBuf);        }        public (int, string) Parse_Int_Tag(byte[] pBuf, out short[] intBuf)        {            intBuf = null;            int nNum = 0;            nNum = pBuf.Length / 2;            if (nNum < 1) return (1, "Parse Failed");            intBuf = new short[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[2] { 0, 0 };                databuf[0] = pBuf[i * 2];                databuf[1] = pBuf[i * 2 + 1];                short iTemp = BitConverter.ToInt16(databuf, 0);                intBuf[i] = iTemp;            }            return (0, "OK");        }        public (int, string) Write_Int_Tag(string strTagName, int nCount, short[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = ShortToBytes(DataBuf);            if (pBuf == null ) return (1, "pBuf is Null");                        (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount,  pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] ShortToBytes(short[] DataBuf)        {            if (DataBuf == null || DataBuf.Length<=0) return null;            int nNum = 0;            //int size = Marshal.SizeOf(typeof(short));            //int size = sizeof(short);            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum*2];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 2] = databuf[0];                bytes[i * 2 + 1] = databuf[1];            }            return bytes;        }        /// <summary>        /// 16bit uint        /// </summary>        /// <param name="strTagName"></param>        /// <param name="nCount"></param>        /// <param name="uintBuf"></param>        /// <returns></returns>        public (int, string) Read_UInt_Tag(string strTagName, int nCount, out UInt16[] uintBuf)        {            byte[] pBuf = null;            uintBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_UInt_Tag(pBuf, out uintBuf);        }        public (int, string) Write_UInt_Tag(string strTagName, int nCount, ushort[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = UShortToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] UShortToBytes(ushort[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;            //int size = Marshal.SizeOf(typeof(short));            //int size = sizeof(short);            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum*2];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 2] = databuf[0];                bytes[i * 2 + 1] = databuf[1];            }            return bytes;        }        public (int, string) Parse_UInt_Tag(byte[] pBuf, out UInt16[] uintBuf)        {            uintBuf = null;            int nNum = 0;            nNum = pBuf.Length / 2;            if (nNum < 1) return (1, "Parse Failed");            uintBuf = new UInt16[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[2] { 0, 0 };                databuf[0] = pBuf[i * 2];                databuf[1] = pBuf[i * 2 + 1];                UInt16 iTemp = BitConverter.ToUInt16(databuf, 0);                uintBuf[i] = iTemp;            }            return (0, "OK");        }        /// <summary>        /// 32bits int        /// </summary>        /// <param name="strTagName"></param>        /// <param name="nCount"></param>        /// <param name="intBuf"></param>        /// <returns></returns>        public (int, string) Read_DInt_Tag(string strTagName, int nCount, out int[] intBuf)        {            byte[] pBuf = null;            intBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_DInt_Tag(pBuf, out intBuf);        }                public (int, string) Write_DInt_Tag(string strTagName, int nCount, int[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = DIntToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] DIntToBytes(int[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;                       nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum*4];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 4] = databuf[0];                bytes[i * 4 + 1] = databuf[1];                bytes[i * 4 + 2] = databuf[2];                bytes[i * 4 + 3] = databuf[3];            }            return bytes;        }        public (int, string) Parse_DInt_Tag(byte[] pBuf, out int[] intBuf)        {            intBuf = null;            int nNum = 0;            nNum = pBuf.Length / 4;            if (nNum < 1) return (1, "Parse Failed");            intBuf = new int[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[4] { 0, 0, 0, 0 };                databuf[0] = pBuf[i * 4];                databuf[1] = pBuf[i * 4 + 1];                databuf[2] = pBuf[i * 4 + 2];                databuf[3] = pBuf[i * 4 + 3];                int iTemp = BitConverter.ToInt32(databuf, 0);                intBuf[i] = iTemp;            }            return (0, "OK");        }        /// <summary>        /// 无符号32位整数        /// </summary>        /// <param name="strTagName"></param>        /// <param name="nCount"></param>        /// <param name="intBuf"></param>        /// <returns></returns>        public (int, string) Read_UDInt_Tag(string strTagName, int nCount, out uint[] uintBuf)        {            byte[] pBuf = null;            uintBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_UDInt_Tag(pBuf, out uintBuf);        }        public (int, string) Write_UDInt_Tag(string strTagName, int nCount, uint[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = UDIntToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] UDIntToBytes(uint[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum * 4];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 4] = databuf[0];                bytes[i * 4 + 1] = databuf[1];                bytes[i * 4 + 2] = databuf[2];                bytes[i * 4 + 3] = databuf[3];            }            return bytes;        }        public (int, string) Parse_UDInt_Tag(byte[] pBuf, out uint[] uintBuf)        {            uintBuf = null;            int nNum = 0;            nNum = pBuf.Length / 4;            if (nNum < 1) return (1, "Parse Failed");            uintBuf = new uint[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[4] { 0, 0, 0, 0 };                databuf[0] = pBuf[i * 4];                databuf[1] = pBuf[i * 4 + 1];                databuf[2] = pBuf[i * 4 + 2];                databuf[3] = pBuf[i * 4 + 3];                uint iTemp = BitConverter.ToUInt32(databuf, 0);                uintBuf[i] = iTemp;            }            return (0, "OK");        }        public (int, string) Read_LInt_Tag(string strTagName, int nCount, out long[] longBuf)        {            byte[] pBuf = null;            longBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_LInt_Tag(pBuf, out longBuf);        }        public (int, string) Write_LInt_Tag(string strTagName, int nCount, long[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = LIntToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] LIntToBytes(long[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum * 8];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 4] = databuf[0];                bytes[i * 4 + 1] = databuf[1];                bytes[i * 4 + 2] = databuf[2];                bytes[i * 4 + 3] = databuf[3];                bytes[i * 4 + 4] = databuf[4];                bytes[i * 4 + 5] = databuf[5];                bytes[i * 4 + 6] = databuf[6];                bytes[i * 4 + 7] = databuf[7];            }            return bytes;        }        public (int, string) Parse_LInt_Tag(byte[] pBuf, out long[] longBuf)        {            longBuf = null;            int nNum = 0;            nNum = pBuf.Length / 8;            if (nNum < 1) return (1, "Parse Failed");            longBuf = new long[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };                databuf[0] = pBuf[i * 4];                databuf[1] = pBuf[i * 4 + 1];                databuf[2] = pBuf[i * 4 + 2];                databuf[3] = pBuf[i * 4 + 3];                databuf[4] = pBuf[i * 4 + 4];                databuf[5] = pBuf[i * 4 + 5];                databuf[6] = pBuf[i * 4 + 6];                databuf[7] = pBuf[i * 4 + 7];                long iTemp = BitConverter.ToInt64(databuf, 0);                longBuf[i] = iTemp;            }            return (0, "OK");        }        /// <summary>        /// 无符号64整数        /// </summary>        /// <param name="strTagName"></param>        /// <param name="nCount"></param>        /// <param name="ulongBuf"></param>        /// <returns></returns>        public (int, string) Read_ULInt_Tag(string strTagName, int nCount, out ulong[] ulongBuf)        {            byte[] pBuf = null;            ulongBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_ULInt_Tag(pBuf, out ulongBuf);        }        public (int, string) Write_ULInt_Tag(string strTagName, int nCount, ulong[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = ULIntToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] ULIntToBytes(ulong[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum * 8];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 4] = databuf[0];                bytes[i * 4 + 1] = databuf[1];                bytes[i * 4 + 2] = databuf[2];                bytes[i * 4 + 3] = databuf[3];                bytes[i * 4 + 4] = databuf[4];                bytes[i * 4 + 5] = databuf[5];                bytes[i * 4 + 6] = databuf[6];                bytes[i * 4 + 7] = databuf[7];            }            return bytes;        }        public (int, string) Parse_ULInt_Tag(byte[] pBuf, out ulong[] ulongBuf)        {            ulongBuf = null;            int nNum = 0;            nNum = pBuf.Length / 8;            if (nNum < 1) return (1, "Parse Failed");            ulongBuf = new ulong[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };                databuf[0] = pBuf[i * 4];                databuf[1] = pBuf[i * 4 + 1];                databuf[2] = pBuf[i * 4 + 2];                databuf[3] = pBuf[i * 4 + 3];                databuf[4] = pBuf[i * 4 + 4];                databuf[5] = pBuf[i * 4 + 5];                databuf[6] = pBuf[i * 4 + 6];                databuf[7] = pBuf[i * 4 + 7];                ulong iTemp = BitConverter.ToUInt64(databuf, 0);                ulongBuf[i] = iTemp;            }            return (0, "OK");        }        public (int, string) Read_Real_Tag(string strTagName, int nCount, out float[] floatBuf)        {            floatBuf = null;            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_Real_Tag(pBuf, out floatBuf);        }        public (int, string) Write_Real_Tag(string strTagName, int nCount, float[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = RealToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] RealToBytes(float[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum * 4];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 4] = databuf[0];                bytes[i * 4 + 1] = databuf[1];                bytes[i * 4 + 2] = databuf[2];                bytes[i * 4 + 3] = databuf[3];            }            return bytes;        }        public (int, string) Parse_Real_Tag(byte[] pBuf, out float[] floatBuf)        {            floatBuf = null;            int nNum = 0;            nNum = pBuf.Length / 4;            floatBuf = new float[nNum];            if (nNum < 1) return (1, "Parse Failed");            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[4] { 0, 0, 0, 0 };                databuf[0] = pBuf[i * 4];                databuf[1] = pBuf[i * 4 + 1];                databuf[2] = pBuf[i * 4 + 2];                databuf[3] = pBuf[i * 4 + 3];                float fTemp = BitConverter.ToSingle(databuf, 0);                floatBuf[i] = fTemp;            }            return (0, "OK");        }        public (int, string) Read_LReal_Tag(string strTagName, int nCount, out double[] doubleBuf)        {            doubleBuf = null;            byte[] pBuf = null;            int nRet = 0;            string strRet = "";                        (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);            if (nRet != 0) return (nRet, strRet);            return Parse_LReal_Tag(pBuf, out doubleBuf);        }        public (int, string) Write_LReal_Tag(string strTagName, int nCount, double[] DataBuf)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            pBuf = LRealToBytes(DataBuf);            if (pBuf == null) return (1, "pBuf is Null");            (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);            return (nRet, strRet);        }        //将转换为Byte数组        public static byte[] LRealToBytes(double[] DataBuf)        {            if (DataBuf == null || DataBuf.Length <= 0) return null;            int nNum = 0;            nNum = DataBuf.Length;            if (nNum < 1) return null;            byte[] bytes = new byte[nNum * 8];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = BitConverter.GetBytes(DataBuf[i]);                bytes[i * 4] = databuf[0];                bytes[i * 4 + 1] = databuf[1];                bytes[i * 4 + 2] = databuf[2];                bytes[i * 4 + 3] = databuf[3];                bytes[i * 4 + 4] = databuf[4];                bytes[i * 4 + 5] = databuf[5];                bytes[i * 4 + 6] = databuf[6];                bytes[i * 4 + 7] = databuf[7];            }            return bytes;        }        public (int, string) Parse_LReal_Tag(byte[] pBuf, out double[] doubleBuf)        {            doubleBuf = null;            int nNum = 0;            nNum = pBuf.Length / 8;            if (nNum < 1) return (1, "Parse Failed");            doubleBuf = new double[nNum];            for (int i = 0; i < nNum; i++)            {                byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };                databuf[0] = pBuf[i * 8];                databuf[1] = pBuf[i * 8 + 1];                databuf[2] = pBuf[i * 8 + 2];                databuf[3] = pBuf[i * 8 + 3];                databuf[4] = pBuf[i * 8 + 4];                databuf[5] = pBuf[i * 8 + 5];                databuf[6] = pBuf[i * 8 + 6];                databuf[7] = pBuf[i * 8 + 7];                double dTemp = BitConverter.ToDouble(databuf, 0);                doubleBuf[i] = dTemp;            }            return (0, "OK");        }        #region 对象与字节数组转化        //将结构体类型转换为Byte数组        public static byte[] StructToBytes(object structObj, int size)        {            byte[] bytes = new byte[size];            IntPtr structPtr = Marshal.AllocHGlobal(size);            try            {                //将结构体拷到分配好的内存空间                Marshal.StructureToPtr(structObj, structPtr, false);                //从内存空间拷贝到byte 数组                Marshal.Copy(structPtr, bytes, 0, size);            }            finally            {                //释放内存空间                Marshal.FreeHGlobal(structPtr);            }            return bytes;        }        //将Byte转换为结构体类型        public static object ByteToStruct(byte[] bytes, Type type)        {            int size = Marshal.SizeOf(type);            if (type.Name == "Boolean") size = 1;            if (size > bytes.Length)            {                return null;            }            //分配结构体内存空间            IntPtr structPtr = Marshal.AllocHGlobal(size);            object obj = null;            try            {                //将byte数组拷贝到分配好的内存空间                Marshal.Copy(bytes, 0, structPtr, size);                //将内存空间转换为目标结构体                obj = Marshal.PtrToStructure(structPtr, type);            }            finally            {                //释放内存空间                Marshal.FreeHGlobal(structPtr);            }            return obj;        }        //将Byte转换为结构体类型        public static Object ByteToStruct2(byte[] bytes, Type type)        {            int size = Marshal.SizeOf(type);            if (type.Name == "Boolean") size = 1;            if (size > bytes.Length)            {                return null;            }            //分配结构体内存空间            IntPtr structPtr = Marshal.AllocHGlobal(size);            object obj = null;            try            {                //将byte数组拷贝到分配好的内存空间                Marshal.Copy(bytes, 0, structPtr, size);                //将内存空间转换为目标结构体                obj = Marshal.PtrToStructure(structPtr, type);            }            finally            {                //释放内存空间                Marshal.FreeHGlobal(structPtr);            }            return obj;        }        public static T ConvertBytesToStruct<T>(byte[] bytes)        {            // 将字节数组转换为结构体            GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);            T myStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));            handle.Free();            return myStruct;        }        #endregion 对象与字节数组转化        /// <summary>        /// 一次读取单个标签        /// </summary>        /// <typeparam name="T">需要读取的标签结构</typeparam>        /// <param name="strTagName">需要读取的标签名</param>        /// <param name="nCount">读取标签的个数</param>        /// <param name="outObj">返回相应标签值对象</param>        /// <returns></returns>        public (int, string) Read_SingleTag<T>(string strTagName, int nCount, out T outObj, Control uiControl)        {            // 初始化输出参数            outObj = default(T);            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            try            {                // 创建一个标志变量,用于判断是否需要显示提示框                bool isProcessingDialogShown = false;                // 启动一个后台任务执行核心逻辑                Task<(int, string)> readTask = Task.Run(() =>                {                    return Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);                });                // 启动一个计时器任务,用于检测是否超过 5 秒                Task delayTask = Task.Delay(5000);                // 等待两个任务中的任意一个完成                Task completedTask = Task.WhenAny(readTask, delayTask).Result;                if (completedTask == delayTask)                {                    // 如果超时,则显示提示框                    ShowProcessingDialog(uiControl);                    isProcessingDialogShown = true;                    // 继续等待读取任务完成                    readTask.Wait();                }                // 获取读取结果                (nRet, strRet) = readTask.Result;                // 检查类型并处理数据                string str = typeof(T).Name;                string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };                bool containsAny = substrings.Any(substring => str.Contains(substring));                if (containsAny)                {                    if (str != strRet) return (120, "变量类型不一致");                }                if (str == "String")                {                    outObj = (T)(object)System.Text.Encoding.UTF8.GetString(pBuf);                }                else                {                    outObj = (T)ByteToStruct(pBuf, typeof(T));                }                // 如果显示了提示框,则关闭它                if (isProcessingDialogShown)                {                    CloseProcessingDialog(uiControl);                }            }            catch (Exception ex)            {                // 异常处理                return (110, ex.ToString());            }            return (nRet, "OK");        }        private Form _processingForm;        private void ShowProcessingDialog(Control uiControl)        {            if (uiControl == null)            {                throw new ArgumentNullException(nameof(uiControl), "UI 控件不能为空。");            }            // 确保在主线程上更新 UI            if (uiControl.InvokeRequired)            {                uiControl.Invoke(new Action(() => ShowProcessingDialog(uiControl)));                return;            }            // 创建并显示提示框            Form processingForm = new Form            {                Text = "请稍候",                Size = new Size(300, 100),                StartPosition = FormStartPosition.CenterScreen,                FormBorderStyle = FormBorderStyle.FixedDialog,                ControlBox = false,                TopMost = true            };            Label label = new Label            {                Text = "正在读取中,请稍后...",                Dock = DockStyle.Fill,                TextAlign = ContentAlignment.MiddleCenter            };            processingForm.Controls.Add(label);            processingForm.Show();            // 保存提示框引用以便后续关闭            _processingForm = processingForm;        }        private void CloseProcessingDialog(Control uiControl)        {            if (uiControl == null)            {                return;            }            // 确保在主线程上更新 UI            if (uiControl.InvokeRequired)            {                uiControl.Invoke(new Action(() => CloseProcessingDialog(uiControl)));                return;            }            // 关闭提示框            _processingForm?.Close();            _processingForm = null;        }        /*        public (int, string) Read_SingleTag<T>(string strTagName, int nCount, out T outObj)        {            outObj = default(T);            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            try            {                (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);                if (nRet != 0) return (nRet, strRet);                string str = typeof(T).Name;                string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };                bool containsAny = substrings.Any(substring => str.Contains(substring));                if (containsAny)                {                    if (str != strRet) return (120, "变量类型不一致");                }                if (str == "String")                {                    outObj = (T)(object)System.Text.Encoding.UTF8.GetString(pBuf);                    return (0, "OK");                }                outObj = (T)ByteToStruct(pBuf, typeof(T));            }            catch (Exception ex)            {                return (110, ex.ToString());            }            return (0, "OK");        }*/        public (int, string) Write_SingleTag<T>(string strTagName, int nCount, T inObj)        {            byte[] pBuf = null;            int nRet = 0;            string strRet = "";            int size = 0;            try            {                string str = typeof(T).Name;                string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };                bool containsAny = substrings.Any(substring => str.Contains(substring));                if (containsAny)                {                    Type type = inObj.GetType();                    if (str != type.Name) return (120, "变量类型不一致");                }                if (str == "String")                {                    //size = inObj.ToString().Length + 1;                    string wtStr= inObj as string;                    pBuf = System.Text.Encoding.Default.GetBytes(wtStr);                    size = pBuf.Length;                }                else                {                    if (typeof(T).Name == "Boolean")                    {                        //pBuf = new byte[1];                        //Type targetType = typeof(T);                        //if ((bool)Convert.ChangeType(inObj, targetType))                        //{                        //    pBuf[0] = 1;                        //}                        //else                        //{                        //    pBuf[0] = 0;                        //}                        size = 1;                    }                    else                    {                        size = Marshal.SizeOf(typeof(T));                                           }                    pBuf = StructToBytes(inObj, size);                }                (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);                return (nRet, strRet);              }            catch (Exception ex)            {                return (110, ex.ToString());            }        }        /// <summary>        /// 一次读取多个标签        /// </summary>        /// <param name="stTagList">需要读取的标签列表信息</param>        /// <param name="outObj">返回的相应标签对象</param>        /// <returns>执行是否成功,非0不成功,以及显示相应的失败信息</returns>        public (int, string) Read_MultiTags(List<StructTag> stTagList, out List<Object> outObj)        {            outObj = new List<Object>();            byte[][] pBuf = null;            int nRet = 0;            string strRet = "";            int nLen = stTagList.Count;            List<StructTag> TagList=new List<StructTag>();            try            {                foreach(StructTag tag in stTagList)                 {                    TagList.Add(new StructTag {strTagName= strTagPrefix + tag.strTagName,tTagType=tag.tTagType,nCount=tag.nCount});                }                        (nRet, strRet) = Read_Tags(TagList, out pBuf);                if (nRet != 0) return (nRet, strRet);                for (int i = 0; i < nLen; i++)                {                    //需要调用的方法                    //MethodInfo mi = typeof(Inovance_EIP).GetMethod("ByteToStruct");                    //该方法的泛型类型Type->typeof(int)                    //MethodInfo miConstructed = mi.MakeGenericMethod(strTagList[i].TagType);                    //var arg = { pBuf[i]};                    //执行调用                    //miConstructed.Invoke(null, args);                    //outObj.Add(Convert.ChangeType(ByteToStruct2(pBuf[i], targetType), targetType));                    Type targetType = TagList[i].tTagType;                    if (targetType != null)                    {                        object obj = ByteToStruct(pBuf[i], targetType);                        //if (obj != null)                        outObj.Add(obj);                    }                }            }            catch (Exception ex)            {                return (110, ex.ToString());            }            return (0, "OK");        }        /// <summary>        /// 一次写多个标签        /// </summary>        /// <param name="stTagList">需要写入的标签列表信息</param>        /// <param name="ObjList">写入的相应标签对象</param>        /// <returns>执行是否成功,非0不成功,以及显示相应的失败信息</returns>        public (int, string) Write_MultiTags(List<StructTag> stTagList, List<Object> ObjList)        {            int nRet = 0;            string strRet = "";                       int nLen = stTagList.Count;            if (ObjList.Count != nLen) return (10, "标签列表和对象列表长度不一致");            List<StructTag> TagList = new List<StructTag>();            try            {                foreach (StructTag tag in stTagList)                {                    TagList.Add(new StructTag { strTagName = strTagPrefix + tag.strTagName, tTagType = tag.tTagType, nCount = tag.nCount });                }                (nRet, strRet) = Write_Tags(TagList, ObjList);                return (nRet, strRet);            }            catch (Exception ex)            {                return (110, ex.ToString());            }        }        #region 清除标签缓存        /// <summary>        /// 清除标签缓存        /// </summary>        public void Clear_TagCache()        {            ResetTagInfo();        }        #endregion 清除标签缓存    }}
 |