Inovance_EIP.cs 125 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280
  1. using Newtonsoft.Json.Linq;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Dynamic;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Runtime.InteropServices;
  10. using System.Runtime.Serialization;
  11. using System.Security.Policy;
  12. using System.Text;
  13. using System.Text.RegularExpressions;
  14. using System.Threading.Tasks;
  15. using System.Windows.Forms;
  16. using System.Xml.Linq;
  17. using static System.Net.Mime.MediaTypeNames;
  18. using static System.Windows.Forms.VisualStyles.VisualStyleElement;
  19. namespace EIP_Protocol
  20. {
  21. #region MES与PLC通讯结构
  22. public enum eMachineState:short
  23. {
  24. Uninitialized=0, //未初始化状态
  25. Initializing, //初始化中...
  26. Initialized, //初始化完成
  27. Running, //运行中
  28. Paused, //暂停状态
  29. Fault, //故障状态
  30. Alarm //报警状态
  31. }
  32. public enum eMesCmd:byte
  33. {
  34. none=0,
  35. InStation = 1, //1:工站进站申请
  36. OutStation =2 //2:工站出站申请
  37. }
  38. public enum eAgvCmd
  39. {
  40. RequestPassingIn = 1, // = 1, AGV请求进料
  41. ConfirmPassInFinish = 2, //= 2, AGV请求进料完成确认
  42. RequestPassingOut = 3, //=3, AGV请求出料
  43. ConfrimPassingOutFinish = 4 //= 4, AGV请求出料完成确认
  44. }
  45. public struct XiaoMiParm
  46. {
  47. public string workstation { get; set; } //装备编码
  48. public string stationCode { get; set; } //工站ID
  49. public string deviceCode { get; set; } //工位编码
  50. }
  51. //图⽚命名需要遵循⼩⽶标准
  52. //[项⽬]_[⼯站]_[SN]_[物料-功能]_[测试时间]_[定位/检测/测量结果]_[是否原图-当前第⼏张-共⼏张]
  53. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  54. public struct CommandToPLC
  55. {
  56. [MarshalAs(UnmanagedType.U1)]
  57. public byte cmd; //1:AGV请求进料 2:AGV请求进料完成确认 3:AGV请求出料 4:AGV请求出料完成确认 PLC:成功回被PC清零
  58. [MarshalAs(UnmanagedType.I2)]
  59. public short cmdParam; //1:左边接口 2:右边接口
  60. [MarshalAs(UnmanagedType.I2)]
  61. public short cmdResult; //指令执行结果 1:OK 110:失败
  62. }
  63. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  64. public struct CommandFromPLC
  65. {
  66. [MarshalAs(UnmanagedType.U1)]
  67. public byte cmd; //1:工站进站申请 2:工站出站申请
  68. [MarshalAs(UnmanagedType.I2)]
  69. public short cmdParam; //指令参数
  70. [MarshalAs(UnmanagedType.I2)]
  71. public short cmdResult; //指令执行结果 1:OK 110:失败
  72. }
  73. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  74. public struct OP10_From_PLC
  75. {
  76. [MarshalAs(UnmanagedType.I4)]
  77. public int nThrowCount; //抛料次数
  78. [MarshalAs(UnmanagedType.R4)]
  79. public float fCleanAirPress; //清洁气压
  80. [MarshalAs(UnmanagedType.R4)]
  81. public float fCleanSpeed; //清洁速度mm/s
  82. [MarshalAs(UnmanagedType.R4)]
  83. public float fWindBladeHeight; //风刀高度mm
  84. [MarshalAs(UnmanagedType.R4)]
  85. public float fCleanTime; //清洁时间S
  86. [MarshalAs(UnmanagedType.I4)]
  87. public int nCleanCount; //清洁次数
  88. }
  89. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  90. public struct OP10_DataSet_t
  91. {
  92. [MarshalAs(UnmanagedType.I4)]
  93. public int nThrowCount; //抛料次数
  94. [MarshalAs(UnmanagedType.R4)]
  95. public float fCleanAirPress; //清洁气压
  96. [MarshalAs(UnmanagedType.R4)]
  97. public float fCleanSpeed; //清洁速度mm/s
  98. [MarshalAs(UnmanagedType.R4)]
  99. public float fWindBladeHeight; //风刀高度mm
  100. [MarshalAs(UnmanagedType.R4)]
  101. public float fCleanTime; //清洁时间S
  102. [MarshalAs(UnmanagedType.I4)]
  103. public int nCleanCount; //清洁次数
  104. [MarshalAs(UnmanagedType.I4)]
  105. public int nRemainCount; //外壳体余料数
  106. }
  107. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  108. public struct IoT_DataSet_t
  109. {
  110. [MarshalAs(UnmanagedType.I2)]
  111. public short machineState; //设备状态
  112. [MarshalAs(UnmanagedType.I2)]
  113. public short work_type; //作业类型:=1 PRESSURE_TEST(压测),=2 POINT_CHECK(点检),=3 OUT_STATION(正常跑料数据)
  114. [MarshalAs(UnmanagedType.I2)]
  115. public short testStatus; //测试状态:=1 PASS 0=FAIL
  116. [MarshalAs(UnmanagedType.I2)]
  117. public short beatAction; //节拍动作 1:上料开始 2:上料结束 3
  118. //:作业开始 4:作业结束 5:下料开始 6:下料结束
  119. [MarshalAs(UnmanagedType.I2)] //节拍返回 1:OK 2:NG
  120. public short beatReturn;
  121. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] //一个单独的位代表一个报警32*10=320
  122. public uint[] fault_codes;
  123. }
  124. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  125. public struct OP20_DataSet_t
  126. {
  127. [MarshalAs(UnmanagedType.I4)]
  128. public int nThrowCount; //抛料次数
  129. [MarshalAs(UnmanagedType.I4)]
  130. public int nRemainCount; //上盖余料数
  131. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  132. public float[] nCeJuData; //测距
  133. }
  134. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  135. public struct OP30_DataSet_t //站数据集
  136. {
  137. [MarshalAs(UnmanagedType.R4)]
  138. public float fGlueSupplySpeed; //供胶速度
  139. [MarshalAs(UnmanagedType.R4)]
  140. public float fAB_AirPress; //AB管气压
  141. [MarshalAs(UnmanagedType.R4)]
  142. public float fAB_AirPressDiff; //AB管气压差
  143. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  144. public float[] fMesHeightInfos; //产品测高信息--点胶前的测高(mm)
  145. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  146. public float[] fIntervalWeights; //可能没有:定期称重数据 A胶,B胶
  147. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  148. public float[] fRemainGlues; //剩余胶量A:0 B:1
  149. }
  150. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  151. public struct OP30_TestData_t //站数据集
  152. {
  153. [MarshalAs(UnmanagedType.R4)]
  154. public float fAB_AirPress; //AB管气压
  155. [MarshalAs(UnmanagedType.R4)]
  156. public float fAB_AirPressMax; //AB管气压(最大值)
  157. [MarshalAs(UnmanagedType.R4)]
  158. public float fAB_AirPressMin; //AB管气压(最小值)
  159. [MarshalAs(UnmanagedType.R4)]
  160. public float fAB_AirPressDiff; //AB管气压差
  161. [MarshalAs(UnmanagedType.R4)]
  162. public float fAB_AirPressDiffMax; //AB管气压差(最大值)
  163. [MarshalAs(UnmanagedType.R4)]
  164. public float fAB_AirPressDiffMin; //AB管气压差(最小值)
  165. }
  166. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  167. public struct OP30_stnDataSet_t
  168. {
  169. public BarcodeSet_t BarcodeSet; //条码集合
  170. public CommandFromPLC mesCommFrmPLC; //MES通讯
  171. public OP30_DataSet_t mesData; //生产参数
  172. public IoT_DataSet_t iotData;
  173. public OP30_TestData_t testData; //测试项
  174. public OP30_OtherData otherData; //其他指令
  175. }
  176. public struct OP30_OtherData
  177. {
  178. [MarshalAs(UnmanagedType.I4)]
  179. public int ChangeA; //左工位 0:取消换胶 1:换胶弹窗 2:扫码完成
  180. [MarshalAs(UnmanagedType.I4)]
  181. public int ChangeB; //右工位 0:取消换胶 1:换胶弹窗 2:扫码完成
  182. }
  183. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  184. public struct OP40_DataSet_t
  185. {
  186. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  187. public float[] fGluePosX; //胶线位置X偏差
  188. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  189. public float[] fGluePosY; //胶线位置Y偏差
  190. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  191. public float[] fGlue_Areas; //胶线面积
  192. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  193. public float[] fGlue_Heights; //胶线高度
  194. [MarshalAs(UnmanagedType.I4)]
  195. public int nResult; //胶线检测结果 1:OK 非1:NG
  196. //public Image TestPic; //测试照片
  197. }
  198. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  199. public struct OP40_TestData_t //测试项
  200. {
  201. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  202. public float[] fGlue_Areas; //胶线面积
  203. [MarshalAs(UnmanagedType.R4)]
  204. public float fGlue_AreasMax; //胶线面积(最大值)
  205. [MarshalAs(UnmanagedType.R4)]
  206. public float fGlue_AreasMin; //胶线面积(最小值)
  207. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  208. public float[] fGlue_Heights; //胶线高度
  209. [MarshalAs(UnmanagedType.R4)]
  210. public float fGlue_HeightsMax; //胶线高度(最大值)
  211. [MarshalAs(UnmanagedType.R4)]
  212. public float fGlue_HeightsMin; //胶线高度(最小值)
  213. }
  214. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  215. public struct OP50_DataSet_t
  216. {
  217. [MarshalAs(UnmanagedType.I4)]
  218. public int nIsAddPCBAsmOK; //是否组装到位
  219. [MarshalAs(UnmanagedType.I4)]
  220. public int nHaveAddPCB; //是否有ADD板
  221. [MarshalAs(UnmanagedType.R4)]
  222. public float fForceAddPCB; //装ADD板的压力
  223. [MarshalAs(UnmanagedType.I4)]
  224. public int nRemainCount; //ADD板余料数
  225. }
  226. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  227. public struct OP50_TestData_t
  228. {
  229. [MarshalAs(UnmanagedType.R4)]
  230. public float fForceAddPCB; //装ADD板的压力
  231. [MarshalAs(UnmanagedType.R4)]
  232. public float fForceAddPCBMax; //装ADD板的压力(最大值)
  233. [MarshalAs(UnmanagedType.R4)]
  234. public float fForceAddPCBMin; //装ADD板的压力(最小值)
  235. }
  236. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  237. public struct OP60_DataSet_t
  238. {
  239. [MarshalAs(UnmanagedType.I4)]
  240. public int nIsTopCoverAsmOK; //是否组装到位
  241. [MarshalAs(UnmanagedType.I4)]
  242. public int nHaveTopCover; //是否有上盖板
  243. [MarshalAs(UnmanagedType.R4)]
  244. public float fForceTopCover; //装上盖板的压力
  245. }
  246. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  247. public struct OP70_DataSet_t
  248. {
  249. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  250. public float[] fScrewTimes; //锁附时间 PLC 14颗螺丝 预留6
  251. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  252. public short[] nScrewOrders; //锁附顺序 PLC 锁螺丝的标号
  253. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  254. public short[] nScrewResults; //锁附结果 PLC
  255. [MarshalAs(UnmanagedType.I4)]
  256. public int nRemainCount; //螺丝余料数
  257. }
  258. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  259. public struct OP70_ScrewDataSet_t
  260. {
  261. [MarshalAs(UnmanagedType.R4)]
  262. public float fTorque; //上位机传到PLC的锁螺丝扭力 每次读到阿特拉斯的数据都传一次
  263. [MarshalAs(UnmanagedType.R4)]
  264. public float fCircles; //上位机传到PLC的锁螺丝圈数 每次读到阿特拉斯的数据都传一次
  265. }
  266. public class OP70_PC_CollectDataSet_t
  267. {
  268. //需要自己收集
  269. public float[] fScrewTorques; //锁附扭力
  270. public float[] fScrewCircles; //锁附圈数
  271. public float[][] fTorqueCurve; //扭力曲线
  272. }
  273. public struct OP70_stnDataSet_t
  274. {
  275. public BarcodeSet_t BarcodeSet; //条码集合
  276. public CommandFromPLC mesCommFrmPLC; //MES通讯
  277. public OP70_DataSet_t mesData;
  278. public IoT_DataSet_t iotData;
  279. public OP70_ScrewDataSet_t screwDataToPLC; //传到PLC的锁螺丝数据,用于HMI显示用
  280. public OP70_OtherData otherData; //其他指令
  281. }
  282. public struct OP70_OtherData
  283. {
  284. [MarshalAs(UnmanagedType.I4)]
  285. public int ChangeA; //左工位 0:取消换螺丝 1:换胶弹窗 2:扫码完成
  286. [MarshalAs(UnmanagedType.I4)]
  287. public int ChangeB; //右工位 0:取消换螺丝 1:换胶弹窗 2:扫码完成
  288. }
  289. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  290. public struct BarcodeSet_t
  291. {
  292. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)] //载具条码
  293. public string strCarrierBarcode;
  294. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)] //产品条码
  295. public string strProductBarcode;
  296. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)] //工位零部件条码
  297. public string strPartBarcode;
  298. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)] //PCB
  299. public string strPCBBarcode;
  300. }
  301. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  302. public struct OP10_MesData_t
  303. {
  304. public BarcodeSet_t BarcodeSet; //条码集合
  305. public CommandToPLC agvCommToPLC; //AGV通讯
  306. public CommandFromPLC mesCommFrmPLC; //MES通讯
  307. public OP10_DataSet_t mesData;
  308. public IoT_DataSet_t iotData;
  309. }
  310. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  311. public struct OP20_MesData_t
  312. {
  313. public BarcodeSet_t BarcodeSet; //条码集合
  314. public CommandToPLC agvCommToPLC; //AGV通讯
  315. public CommandFromPLC mesCommFrmPLC; //MES通讯
  316. public OP20_DataSet_t mesData;
  317. public IoT_DataSet_t iotData;
  318. }
  319. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  320. public struct OP30_MesData_t
  321. {
  322. public OP30_stnDataSet_t Left;
  323. public OP30_stnDataSet_t Right;
  324. }
  325. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  326. public struct OP40_MesData_t
  327. {
  328. public BarcodeSet_t BarcodeSet; //条码集合
  329. public CommandFromPLC mesCommFrmPLC; //MES通讯
  330. public OP40_DataSet_t mesData;
  331. public IoT_DataSet_t iotData;
  332. public OP40_TestData_t testData; //测试项
  333. }
  334. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  335. public struct OP50_MesData_t
  336. {
  337. public BarcodeSet_t BarcodeSet; //条码集合
  338. public CommandToPLC agvCommToPLC; //AGV通讯
  339. public CommandFromPLC mesCommFrmPLC; //MES通讯
  340. public OP50_DataSet_t mesData;
  341. public IoT_DataSet_t iotData;
  342. public OP50_TestData_t testData; //测试项
  343. }
  344. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  345. public struct OP60_MesData_t
  346. {
  347. public BarcodeSet_t BarcodeSet; //条码集合
  348. public CommandFromPLC mesCommFrmPLC; //MES通讯
  349. public OP60_DataSet_t mesData;
  350. public IoT_DataSet_t iotData;
  351. }
  352. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  353. public struct OP70_iotDataSet_t
  354. {
  355. public IoT_DataSet_t Left;
  356. public IoT_DataSet_t Right;
  357. }
  358. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  359. public struct OP70_MesData_t
  360. {
  361. public OP70_stnDataSet_t Left;
  362. public OP70_stnDataSet_t Right;
  363. }
  364. public struct OP80_DataSet_t
  365. {
  366. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  367. public float[] fScrewHeights; //螺丝高度 PLC 14颗螺丝 预留6
  368. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  369. public short[] nScrewResults; //螺丝检测结果 PLC 1:OK 0:NG
  370. }
  371. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  372. public struct OP80_MesData_t
  373. {
  374. public BarcodeSet_t BarcodeSet; //条码集合
  375. public CommandFromPLC mesCommFrmPLC; //MES通讯
  376. public OP80_DataSet_t mesData;
  377. public IoT_DataSet_t iotData;
  378. }
  379. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  380. public struct OP90_DataSet_t
  381. {
  382. [MarshalAs(UnmanagedType.I4)]
  383. public int nThrowCount; //抛料次数
  384. [MarshalAs(UnmanagedType.I4)]
  385. public int nRemainCount; //料箱余料数
  386. }
  387. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  388. public struct OP90_MesData_t
  389. {
  390. public BarcodeSet_t BarcodeSet; //条码集合
  391. public CommandToPLC agvCommToPLC; //AGV通讯
  392. public CommandFromPLC mesCommFrmPLC; //MES通讯
  393. public OP90_DataSet_t mesData;
  394. public IoT_DataSet_t iotData;
  395. }
  396. #endregion MES与PLC通讯结构
  397. public class Inovance_EIP
  398. {
  399. private string strTagPrefix = "Application.GVL."; //标签前缀,80站是Application.GVL_HMI.,不知道为什么反正就是这样
  400. private object m_objLock = new object();
  401. bool isStart = false;
  402. string strClaimedComputerIP = ""; //PC的IP地址 - private实际IP
  403. private int m_nInstanceId = 0; //实例ID
  404. public bool m_bConnected = false;
  405. public string _pcIPStr = string.Empty; //PC的IP地址
  406. public string _plcIPStr = string.Empty; //PLC的IP地址
  407. public bool IsConnected
  408. {
  409. get { return m_bConnected; }
  410. }
  411. public void Config_TagPrefix(string TagPrefix)
  412. {
  413. strTagPrefix = TagPrefix;
  414. }
  415. #region 自定义的结构
  416. public enum ERROR_NO : int
  417. {
  418. ERR_EIP_STOPED = -2,//协议栈未开启
  419. OTHER_ERROR = -1,
  420. SUCCESS = 0,
  421. ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED = 1,//连接的实例ID与已有的ID重复或超过最大值
  422. ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH,//连接的网络路径格式错误,无法检测出来目标IP离线等错误
  423. ERRI_CONNECTION_COUNT_LIMIT_REACHED,//达到最大连接数量
  424. ERRI_OUT_OF_MEMORY,//内存溢出,缓冲区已满
  425. ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH, //连接的网络地址无效
  426. ERRR_CONN_CONFIG_FAILED_NO_RESPONSE, //连接无响应
  427. ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE,//连接响应错误
  428. ERRR_INVALID_DESTINATION, //目标标签不存在
  429. ERRR_TAGNAME_TOO_LONG, //标签名超过255字节
  430. ERRR_REQUEST_DATA_TOO_LARGE, //请求数据超限
  431. ERRR_CONN_CONNECTION_TIMED_OUT, //活动连接响应超时,请检查目标IP是否离线
  432. ERRR_TAGNAME_CONVERT_FAILED, //标签名解析错误
  433. ERRR_WRITE_DATASIZE_UNCONSISTENT, //数据长度与标签实际长度不一致
  434. ERRR_SCAN_ERROR, //扫描标签信息失败
  435. };
  436. public enum TAG_TYPE : int
  437. {
  438. TAG_TYPE_UNDEFINE = -1,
  439. TAG_TYPE_BOOL = 0xC1, //新增
  440. TAG_TYPE_SINT = 0xC2,
  441. TAG_TYPE_INT = 0xC3,
  442. TAG_TYPE_DINT = 0xC4,
  443. TAG_TYPE_LINT = 0xC5,
  444. TAG_TYPE_USINT = 0xC6,
  445. TAG_TYPE_UINT = 0xC7,
  446. TAG_TYPE_UDINT = 0xC8,
  447. TAG_TYPE_ULINT = 0xC9,
  448. TAG_TYPE_REAL = 0xCA,
  449. TAG_TYPE_LREAL = 0xCB,
  450. TAG_TYPE_STRING = 0xD0, //新增
  451. TAG_TYPE_BYTE = 0xD1,
  452. TAG_TYPE_WORD = 0xD2,
  453. TAG_TYPE_DWORD = 0xD3,
  454. TAG_TYPE_LWORD = 0xD4,
  455. TAG_TYPE_STRUCT = 0xA2, //新增
  456. TAG_TYPE_ARRAY = 0xA3
  457. };
  458. enum EtIPConnectionState : int
  459. {
  460. ConnectionNonExistent = 0x0, //该实例未有连接
  461. ConnectionConfiguring = 0x1, //连接正在打开过程中
  462. ConnectionEstablished = 0x3, //连接已成功建立并在活动中
  463. ConnectionTimedOut = 0x4, //连接超时
  464. ConnectionClosing = 0x6 //连接正在关闭中
  465. };
  466. public const uint INVALID_MEMBER = 0xffffffff; //Member is not valid flag should be used when no member should be specified in the UCMM
  467. public struct tagTagReadData
  468. {
  469. public string pName;
  470. public int nElementCount;
  471. public int nArrayPos;
  472. };
  473. public struct tagTagReadDataBase
  474. {
  475. public string pName;
  476. public int nElementCount;
  477. };
  478. public struct tagTagRetValue
  479. {
  480. public IntPtr pData;
  481. public TAG_TYPE pType;
  482. public int nDataLength;
  483. //tagTagRetValue()
  484. //{
  485. // pData = NULL;
  486. // pType = TAG_TYPE_UNDEFINE;
  487. // nDataLength = 0;
  488. //}
  489. //~tagTagRetValue()
  490. //{
  491. // if (pData)
  492. // {
  493. // delete pData;
  494. // pData = NULL;
  495. // }
  496. //}
  497. };
  498. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
  499. public struct tagTagWriteData
  500. {
  501. public string pName;
  502. public IntPtr pData;
  503. public TAG_TYPE pType;
  504. public int nArrayPos;
  505. public int nDataLength;
  506. public int nElementCount;
  507. };
  508. public struct tagTagWriteDataBase
  509. {
  510. public string pName;
  511. public IntPtr pData;
  512. public TAG_TYPE pType;
  513. public int nDataLength;
  514. public int nElementCount;
  515. };
  516. public class MySerializationBinder : SerializationBinder
  517. {
  518. public override Type BindToType(string assemblyName, string typeName)
  519. {
  520. // 如果类型名称是"MyNamespace.MyUnsupportedType",则将其转换为"MyNamespace.MySupportType"
  521. if (typeName == "MyNamespace.MyUnsupportedType")
  522. {
  523. return Type.GetType("MyNamespace.MySupportType");
  524. }
  525. // 否则返回null,表示无法进行转换
  526. return null;
  527. }
  528. }
  529. #endregion 自定义的结构
  530. #region 动态类型
  531. public class DynamicMethodProvider
  532. {
  533. public dynamic GetDynamicValue(string propertyName)
  534. {
  535. dynamic result;
  536. switch (propertyName)
  537. {
  538. case "Name":
  539. result = "John Doe";
  540. break;
  541. case "Age":
  542. result = 30;
  543. break;
  544. default:
  545. result = new ExpandoObject();
  546. ((IDictionary<string, object>)result).Add("UnknownProperty", "UnknownValue");
  547. break;
  548. }
  549. return result;
  550. }
  551. }
  552. public static T CreateElement<T>()
  553. {
  554. Type t = typeof(T);
  555. return (T)t.Assembly.CreateInstance(t.FullName);
  556. }
  557. public static dynamic CreateElement(string typename)
  558. {
  559. Type t = GetTypeByName(typename);
  560. return t.Assembly.CreateInstance(t.FullName);
  561. }
  562. public static Type GetTypeByName(string typename)
  563. {
  564. Type t = null;
  565. string source = typename;
  566. try
  567. {
  568. t = Type.GetType(source);
  569. if (t != null)
  570. {
  571. return t;
  572. }
  573. Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();
  574. foreach (Assembly ass in assembly)
  575. {
  576. t = ass.GetType(source);
  577. if (t != null)
  578. {
  579. return t;
  580. }
  581. Type[] ts = ass.GetTypes();
  582. foreach (Type st in ts)
  583. {
  584. if (Regex.IsMatch(st.FullName, @"\." + source + @"(`?\d+)?$"))
  585. {
  586. return st;
  587. }
  588. }
  589. }
  590. }
  591. catch (Exception ex)
  592. {
  593. }
  594. return t;
  595. }
  596. public static Type GetTypeByName2(string typename)
  597. {
  598. Type t = null;
  599. string source = typename;
  600. if (source.IndexOf('<') > 0)
  601. {
  602. List<string> lv = new List<string>();
  603. while (Regex.IsMatch(source, @"<[^<>]+>"))
  604. {
  605. lv.Add(Regex.Match(source, @"(?<=<)[^<>]+(?=>)").Value);
  606. source = Regex.Replace(source, @"<[^<>]+>", "/" + (lv.Count - 1));
  607. }
  608. List<Type[]> args = new List<Type[]>();
  609. for (int i = 0; i < lv.Count; i++)
  610. {
  611. List<Type> arg = new List<Type>();
  612. string[] sp = lv[i].Split(',');
  613. for (int j = 0; j < sp.Length; j++)
  614. {
  615. string s = sp[j].Trim();
  616. if (!string.IsNullOrEmpty(s))
  617. {
  618. if (Regex.IsMatch(s, @"/\d+$"))
  619. {
  620. Match m = Regex.Match(s, @"^([^/\s]+)\s*/(\d+)$");
  621. if (!m.Success)
  622. {
  623. throw new Exception("");
  624. }
  625. Type p = GetTypeByName(m.Groups[1].Value);
  626. Type c = p.MakeGenericType(args[Convert.ToInt32(m.Groups[2].Value)]);
  627. arg.Add(c);
  628. }
  629. else
  630. {
  631. arg.Add(GetTypeByName(s));
  632. }
  633. }
  634. }
  635. args.Add(arg.ToArray());
  636. }
  637. Match f = Regex.Match(source, @"^([^/\s]+)\s*/(\d+)$");
  638. if (!f.Success)
  639. {
  640. throw new Exception("");
  641. }
  642. Type fp = GetTypeByName(f.Groups[1].Value);
  643. Type fc = fp.MakeGenericType(args[Convert.ToInt32(f.Groups[2].Value)]);
  644. return fc;
  645. }
  646. else
  647. {
  648. try
  649. {
  650. t = Type.GetType(source);
  651. if (t != null)
  652. {
  653. return t;
  654. }
  655. Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();
  656. foreach (Assembly ass in assembly)
  657. {
  658. t = ass.GetType(source);
  659. if (t != null)
  660. {
  661. return t;
  662. }
  663. Type[] ts = ass.GetTypes();
  664. foreach (Type st in ts)
  665. {
  666. //if (Regex.IsMatch(st.FullName, @"\." + Regex.FormatRegEx(source) + @"(`?\d+)?$"))
  667. if (Regex.IsMatch(st.FullName, @"\." + source + @"(`?\d+)?$"))
  668. {
  669. return st;
  670. }
  671. }
  672. }
  673. }
  674. catch (Exception ex)
  675. {
  676. }
  677. }
  678. return t;
  679. }
  680. #endregion 动态类型
  681. #region DLL
  682. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  683. public static extern void EipStart();
  684. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  685. public static extern void EipStop();
  686. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  687. public static extern int EipOpenConnection(string ipAddress, IntPtr instanceID);
  688. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  689. public static extern int EipCloseConnection(int nID);
  690. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  691. public static extern int EipReadTag(int instanceID, string tagName, IntPtr type, byte[] dest, int dataLength, ushort elementCount = 1, uint nPos = INVALID_MEMBER);
  692. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  693. 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*/);
  694. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  695. public static extern int EipGetConnectionState(int nID);
  696. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  697. public static extern bool EipStartExt(string ipAddress, uint nPort = 0);
  698. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  699. public static extern int EipReadTagList(int instanceID, int nNumOfTags, tagTagReadData[] pTagList, ref tagTagRetValue pdest);
  700. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  701. public static extern ERROR_NO EipWriteTagList(int instanceID, int nNumOfTags, tagTagWriteData[] pTagWritenData);
  702. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  703. public static extern bool DeleteTagListStru(ref tagTagRetValue pRetValue, int nNumOfTags);
  704. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  705. public static extern int EipReadTagExt(int instanceID, string tagName, IntPtr type, byte[] dest, int dataLength, ushort elementCount = 1);
  706. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  707. public static extern int EipWriteTagExt(int instanceID, string tagName, int type, byte[] source, int dataLength, ushort elementCount = 1);
  708. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  709. public static extern int EipReadTagListExt(int instanceID, int nNumOfTags, tagTagReadDataBase[] pTagList, ref tagTagRetValue pdest, bool bScan = false);
  710. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  711. public static extern ERROR_NO EipWriteTagListExt(int instanceID, int nNumOfTags, tagTagWriteDataBase[] pTagWritenData, bool bScan = false);
  712. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  713. public static extern ERROR_NO EipReadTagExt2(int iInstanceID, tagTagReadDataBase[] pTagList, ref tagTagRetValue pDest);
  714. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  715. public static extern ERROR_NO EipWriteTagExt2(int iInstanceID, tagTagWriteDataBase[] pTagWritenData);
  716. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  717. public static extern void ResetTagInfo();
  718. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  719. public static extern ERROR_NO EipReadTagRaw(int iInstanceID, tagTagReadDataBase[] pTagList, ref tagTagRetValue pDest);
  720. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  721. public static extern ERROR_NO EipWriteTagRaw(int iInstanceID, tagTagWriteDataBase[] pTagWritenData);
  722. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  723. public static extern int EipReadTagListRaw(int instanceID, int nNumOfTags, tagTagReadDataBase[] pTagList, ref tagTagRetValue pdest);
  724. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  725. public static extern ERROR_NO EipWriteTagListRaw(int instanceID, int nNumOfTags, tagTagWriteDataBase[] pTagWritenData);
  726. #endregion DLL
  727. #region private方法
  728. private string getTypeString(TAG_TYPE eType)
  729. {
  730. string strType = "";
  731. switch (eType)
  732. {
  733. case TAG_TYPE.TAG_TYPE_SINT:
  734. strType = "SINT";
  735. break;
  736. case TAG_TYPE.TAG_TYPE_INT:
  737. strType = "INT";
  738. break;
  739. case TAG_TYPE.TAG_TYPE_DINT:
  740. strType = "DINT";
  741. break;
  742. case TAG_TYPE.TAG_TYPE_LINT:
  743. strType = "LINT";
  744. break;
  745. case TAG_TYPE.TAG_TYPE_USINT:
  746. strType = "USINT";
  747. break;
  748. case TAG_TYPE.TAG_TYPE_UINT:
  749. strType = "UINT";
  750. break;
  751. case TAG_TYPE.TAG_TYPE_UDINT:
  752. strType = "UDINT";
  753. break;
  754. case TAG_TYPE.TAG_TYPE_ULINT:
  755. strType = "ULINT";
  756. break;
  757. case TAG_TYPE.TAG_TYPE_REAL:
  758. strType = "REAL";
  759. break;
  760. case TAG_TYPE.TAG_TYPE_LREAL:
  761. strType = "LREAL";
  762. break;
  763. case TAG_TYPE.TAG_TYPE_BYTE:
  764. strType = "BYTE";
  765. break;
  766. case TAG_TYPE.TAG_TYPE_WORD:
  767. strType = "WORD";
  768. break;
  769. case TAG_TYPE.TAG_TYPE_DWORD:
  770. strType = "DWORD";
  771. break;
  772. case TAG_TYPE.TAG_TYPE_LWORD:
  773. strType = "LWORD";
  774. break;
  775. case TAG_TYPE.TAG_TYPE_BOOL:
  776. strType = "BOOL";
  777. break;
  778. case TAG_TYPE.TAG_TYPE_STRING:
  779. strType = "STRING";
  780. break;
  781. case TAG_TYPE.TAG_TYPE_STRUCT:
  782. strType = "STRUCT";
  783. break;
  784. default:
  785. break;
  786. }
  787. return strType;
  788. }
  789. private byte[] StringToBytes(string s)
  790. {
  791. string[] str = s.Split(' ');
  792. int n = str.Length;
  793. byte[] cmdBytes = null;
  794. int p = 0;
  795. for (int k = 0; k < n; k++)
  796. {
  797. int sLen = str[k].Length;
  798. int bytesLen = sLen / 2;
  799. int position = 0;
  800. byte[] bytes = new byte[bytesLen];
  801. for (int i = 0; i < bytesLen; i++)
  802. {
  803. string abyte = str[k].Substring(position, 2);
  804. bytes[i] = Convert.ToByte(abyte, 16);
  805. position += 2;
  806. }
  807. if (position >= 2)
  808. {
  809. byte[] cmdBytes2 = new byte[p + bytesLen];
  810. if (cmdBytes != null)
  811. {
  812. Array.Copy(cmdBytes, 0, cmdBytes2, 0, p);
  813. }
  814. Array.Copy(bytes, 0, cmdBytes2, p, bytesLen);
  815. cmdBytes = cmdBytes2;
  816. p += bytesLen;
  817. }
  818. }
  819. return cmdBytes;
  820. }
  821. private (int,string) OpenEip(string strLocalComputerIp)
  822. {
  823. //limit input of controller
  824. bool blnTest = false;
  825. bool bValidIP = true;
  826. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  827. blnTest = regex.IsMatch(strLocalComputerIp);
  828. if (blnTest == true)
  829. {
  830. string[] strTemp = strLocalComputerIp.Split(new char[] { '.' });
  831. if (strTemp.Length < 4)
  832. {
  833. bValidIP = false;
  834. return (-1, "不符合IP格式");
  835. }
  836. for (int i = 0; (i < strTemp.Length) && bValidIP; i++)
  837. {
  838. if (Convert.ToInt32(strTemp[i]) > 255)
  839. {
  840. //大于255则提示,不符合IP格式
  841. bValidIP = false;
  842. return (-2, "IP大于255,不符合IP格式");
  843. }
  844. }
  845. }
  846. else
  847. {
  848. //输入非数字则提示,不符合IP格式
  849. bValidIP = false;
  850. return (-3, "输入非数字,不符合IP格式");
  851. }
  852. if (bValidIP)
  853. {
  854. if (!isStart)
  855. {
  856. if (EipStartExt(strLocalComputerIp, 0))
  857. {
  858. isStart = true;
  859. strClaimedComputerIP = strLocalComputerIp;
  860. return (0, "EIP协议栈开启成功");
  861. }
  862. else
  863. {
  864. isStart = false;
  865. return (1, "EIP协议栈开启失败");
  866. }
  867. }
  868. else
  869. {
  870. if (string.Compare(strClaimedComputerIP, strLocalComputerIp) != 0)
  871. {
  872. return (2,"更改上位机IP时需先关闭协议栈,再开启");
  873. }
  874. else
  875. {
  876. return (3, "EIP协议栈已经开启");
  877. }
  878. }
  879. }
  880. return (-4, "无效IP");
  881. }
  882. private (bool,string) CloseEip()
  883. {
  884. if (isStart)
  885. {
  886. EipStop();
  887. isStart = false;
  888. return (true, "EIP协议栈关闭");
  889. }
  890. else
  891. {
  892. return (false, "EIP协议栈未开启,请先开启");
  893. }
  894. }
  895. #endregion private方法
  896. #region 连接/断开
  897. #region 连接方式 一
  898. public Inovance_EIP() { }
  899. /// <summary>
  900. /// 连接PLC
  901. /// </summary>
  902. /// <param name="strComputerIp">PC的IP地址</param>
  903. /// <param name="strPlcIp">PLC的IP地址</param>
  904. /// <returns>成功:True 失败:False </returns>
  905. public (int,string) Connect(string strComputerIp,string strPlcIp)
  906. {
  907. _pcIPStr = strComputerIp;
  908. _plcIPStr = strPlcIp;
  909. lock (m_objLock)
  910. {
  911. string strRet = "";
  912. int nRet = 0;
  913. if (!isStart) (nRet, strRet) = OpenEip(strComputerIp);
  914. if (nRet != 0) return (nRet, strRet);
  915. bool blnTest = false;
  916. bool bValidIP = true;
  917. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  918. blnTest = regex.IsMatch(strPlcIp);
  919. if (blnTest == true)
  920. {
  921. string[] strTemp = strPlcIp.Split(new char[] { '.' });
  922. for (int i = 0; i < strTemp.Length; i++)
  923. {
  924. if (Convert.ToInt32(strTemp[i]) > 255)
  925. {
  926. bValidIP = false;
  927. return (-10, "PLC IP 大于255,不符合IP格式");
  928. }
  929. }
  930. }
  931. else
  932. {
  933. bValidIP = false;
  934. return (-11, "PLC IP输入非数字,不符合IP格式");
  935. }
  936. if (bValidIP)
  937. {
  938. if (strPlcIp.CompareTo(strClaimedComputerIP) == 0)
  939. {
  940. string strLog = "";
  941. strLog += "上位机IP与PLC IP相同,请重新输入";
  942. return (-20, strLog);
  943. }
  944. if (strPlcIp.CompareTo(strComputerIp) == 0)
  945. {
  946. string strLog = "";
  947. strLog += "上位机IP与PLC IP相同,请重新输入";
  948. return (-21, strLog);
  949. }
  950. int instanceId = 0;
  951. ERROR_NO errorNo;
  952. unsafe
  953. {
  954. errorNo = (ERROR_NO)EipOpenConnection(strPlcIp, (IntPtr)(&instanceId));
  955. }
  956. m_nInstanceId = instanceId;
  957. string str = "";
  958. str += "\n请求创建PLC连接 ip:";
  959. str += strPlcIp;
  960. str += " ";
  961. if (errorNo != ERROR_NO.SUCCESS)
  962. {
  963. m_bConnected = false;
  964. str += ("失败 ");
  965. switch (errorNo)
  966. {
  967. case ERROR_NO.ERR_EIP_STOPED:
  968. str += ("协议栈未开启");
  969. break;
  970. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  971. str += ("连接的实例ID与已有的ID重复或超过最大值");
  972. break;
  973. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  974. str += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  975. break;
  976. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  977. str += ("达到最大连接数量");
  978. break;
  979. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  980. str += ("内存溢出,缓冲区已满");
  981. break;
  982. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  983. str += ("连接的网络地址无效");
  984. break;
  985. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  986. str += ("连接无响应");
  987. break;
  988. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  989. str += ("连接响应错误");
  990. break;
  991. default:
  992. str += ("其他错误");
  993. break;
  994. }
  995. }
  996. else
  997. {
  998. str += "成功";
  999. str += " 分配的实例ID 为 ";
  1000. str += instanceId.ToString();
  1001. m_bConnected = true;
  1002. return (0, str);
  1003. }
  1004. str += "\n";
  1005. return (100 + (int)errorNo, str);
  1006. }
  1007. }
  1008. return (1000, "Error");
  1009. }
  1010. #endregion 连接方式 一
  1011. #region 连接方式 二
  1012. /// <summary>
  1013. ///
  1014. /// </summary>
  1015. /// <param name="strComputerIp">PC的IP地址</param>
  1016. /// <param name="strPlcIp">PLC的IP地址</param>
  1017. public Inovance_EIP(string strComputerIp, string strPlcIp)
  1018. {
  1019. _pcIPStr = strComputerIp;
  1020. _plcIPStr = strPlcIp;
  1021. }
  1022. /// <summary>
  1023. /// 连接PLC
  1024. /// </summary>
  1025. /// <returns>成功:True 失败:False </returns>
  1026. public (int, string) Connect()
  1027. {
  1028. lock (m_objLock)
  1029. {
  1030. string strRet = "";
  1031. int nRet = 0;
  1032. if (!isStart) (nRet, strRet) = OpenEip(_pcIPStr);
  1033. if (nRet != 0) return (nRet, strRet);
  1034. bool blnTest = false;
  1035. bool bValidIP = true;
  1036. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  1037. blnTest = regex.IsMatch(_plcIPStr);
  1038. if (blnTest == true)
  1039. {
  1040. string[] strTemp = _plcIPStr.Split(new char[] { '.' });
  1041. for (int i = 0; i < strTemp.Length; i++)
  1042. {
  1043. if (Convert.ToInt32(strTemp[i]) > 255)
  1044. {
  1045. bValidIP = false;
  1046. return (-10, "PLC IP 大于255,不符合IP格式");
  1047. }
  1048. }
  1049. }
  1050. else
  1051. {
  1052. bValidIP = false;
  1053. return (-11, "PLC IP输入非数字,不符合IP格式");
  1054. }
  1055. if (bValidIP)
  1056. {
  1057. if (_plcIPStr.CompareTo(strClaimedComputerIP) == 0)
  1058. {
  1059. string strLog = "";
  1060. strLog += "上位机IP与PLC IP相同,请重新输入";
  1061. return (-20, strLog);
  1062. }
  1063. if (_plcIPStr.CompareTo(_pcIPStr) == 0)
  1064. {
  1065. string strLog = "";
  1066. strLog += "上位机IP与PLC IP相同,请重新输入";
  1067. return (-21, strLog);
  1068. }
  1069. int instanceId = 0;
  1070. ERROR_NO errorNo;
  1071. unsafe
  1072. {
  1073. errorNo = (ERROR_NO)EipOpenConnection(_plcIPStr, (IntPtr)(&instanceId));
  1074. }
  1075. m_nInstanceId = instanceId;
  1076. string str = "";
  1077. str += "\n请求创建PLC连接 ip:";
  1078. str += _plcIPStr;
  1079. str += " ";
  1080. if (errorNo != ERROR_NO.SUCCESS)
  1081. {
  1082. m_bConnected = false;
  1083. str += ("失败 ");
  1084. switch (errorNo)
  1085. {
  1086. case ERROR_NO.ERR_EIP_STOPED:
  1087. str += ("协议栈未开启");
  1088. break;
  1089. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1090. str += ("连接的实例ID与已有的ID重复或超过最大值");
  1091. break;
  1092. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1093. str += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1094. break;
  1095. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1096. str += ("达到最大连接数量");
  1097. break;
  1098. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1099. str += ("内存溢出,缓冲区已满");
  1100. break;
  1101. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1102. str += ("连接的网络地址无效");
  1103. break;
  1104. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1105. str += ("连接无响应");
  1106. break;
  1107. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1108. str += ("连接响应错误");
  1109. break;
  1110. default:
  1111. str += ("其他错误");
  1112. break;
  1113. }
  1114. }
  1115. else
  1116. {
  1117. str += "成功";
  1118. str += " 分配的实例ID 为 ";
  1119. str += instanceId.ToString();
  1120. m_bConnected = true;
  1121. return (0, str);
  1122. }
  1123. str += "\n";
  1124. return (100 + (int)errorNo, str);
  1125. }
  1126. }
  1127. return (1000, "Error");
  1128. }
  1129. #endregion 连接方式 二
  1130. /// <summary>
  1131. /// 断开连接
  1132. /// </summary>
  1133. /// <returns>成功:True 失败:False</returns>
  1134. public bool Disconnect()
  1135. {
  1136. lock (m_objLock)
  1137. {
  1138. if (m_nInstanceId == 0 || !m_bConnected)
  1139. {
  1140. m_nInstanceId = 0;
  1141. m_bConnected = false;
  1142. return true;
  1143. }
  1144. ERROR_NO errorNo = (ERROR_NO)EipCloseConnection(m_nInstanceId);
  1145. //string str = "";
  1146. if (errorNo != ERROR_NO.SUCCESS)
  1147. {
  1148. //str += "失败";
  1149. m_bConnected = false;
  1150. m_nInstanceId = 0;
  1151. return false;
  1152. }
  1153. else
  1154. {
  1155. //str += "成功";
  1156. m_bConnected = false;
  1157. m_nInstanceId = 0;
  1158. CloseEip();
  1159. return true;
  1160. }
  1161. }
  1162. }
  1163. #endregion 连接/断开
  1164. public (int,string) Read_Tag(string strTagName, int nCount, out byte[] pBuf)
  1165. {
  1166. pBuf = null;
  1167. string strType = "";
  1168. lock (m_objLock)
  1169. {
  1170. if (!m_bConnected) return (-1,"未连接");
  1171. string tagName = strTagName;
  1172. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(tagName);
  1173. if (m_nInstanceId <= 0)
  1174. {
  1175. return (-2, "实例ID需大于0");
  1176. }
  1177. if (tagNameUTF8.Length > 255)
  1178. {
  1179. return (-3, "标签名长度超过255字节");
  1180. }
  1181. ushort elementCount = (ushort)nCount;
  1182. if (elementCount > 0)
  1183. {
  1184. int destLength = 1400;
  1185. byte[] dest = new byte[destLength];
  1186. char[] cChar = Encoding.ASCII.GetChars(dest);
  1187. //TAG_TYPE type = TAG_TYPE.TAG_TYPE_UNDEFINE;
  1188. //int returnLength = 0;
  1189. tagTagReadDataBase[] pTaglist = new tagTagReadDataBase[1];
  1190. pTaglist[0].pName = tagName;
  1191. pTaglist[0].nElementCount = elementCount;
  1192. tagTagRetValue[] tagValue = new tagTagRetValue[1];
  1193. ERROR_NO errorNo = ERROR_NO.OTHER_ERROR;
  1194. unsafe
  1195. {
  1196. errorNo = EipReadTagExt2(m_nInstanceId, pTaglist, ref tagValue[0]);
  1197. }
  1198. string strLog = "";
  1199. strLog += "读取请求";
  1200. if (/*returnLength < 0*/errorNo != ERROR_NO.SUCCESS)
  1201. {
  1202. strLog += " 失败 标签名:" + tagName + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1203. switch (/*returnLength*/errorNo)
  1204. {
  1205. //case -1:
  1206. // strLog += ("其他错误");
  1207. // break;
  1208. //case -2:
  1209. // strLog += ("协议栈未开启");
  1210. // break;
  1211. //case -3:
  1212. // strLog += ("实例id小于或等于0");
  1213. // break;
  1214. //case -4:
  1215. // strLog += ("标签名长度大于255字节");
  1216. // break;
  1217. //case -5:
  1218. // strLog += ("目标标签不存在");
  1219. // break;
  1220. //case -6:
  1221. // strLog += ("响应超时,请检查设备是否离线");
  1222. // break;
  1223. //case -7:
  1224. // strLog += ("标签名解析错误");
  1225. // break;
  1226. //case -8:
  1227. // strLog += ("扫描标签信息失败");
  1228. // break;
  1229. //default:
  1230. // strLog += ("其他错误");
  1231. // break;
  1232. case ERROR_NO.ERR_EIP_STOPED:
  1233. strLog += ("协议栈未开启");
  1234. break;
  1235. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1236. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1237. break;
  1238. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1239. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1240. break;
  1241. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1242. strLog += ("达到最大连接数量");
  1243. break;
  1244. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1245. strLog += ("内存溢出,缓冲区已满");
  1246. break;
  1247. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1248. strLog += ("连接的网络地址无效");
  1249. break;
  1250. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1251. strLog += ("连接无响应");
  1252. break;
  1253. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1254. strLog += ("连接响应错误");
  1255. break;
  1256. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1257. strLog += ("目标标签不存在");
  1258. break;
  1259. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1260. strLog += ("标签名超过255字节");
  1261. break;
  1262. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1263. strLog += ("请求数据超限");
  1264. break;
  1265. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1266. strLog += ("响应超时,请检查设备是否离线");
  1267. break;
  1268. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1269. strLog += ("标签名解析错误");
  1270. break;
  1271. case ERROR_NO.ERRR_SCAN_ERROR:
  1272. strLog += ("扫描标签信息失败");
  1273. break;
  1274. default:
  1275. strLog += ("其他错误");
  1276. break;
  1277. }
  1278. strLog += "\n";
  1279. return (10,strLog);
  1280. }
  1281. else
  1282. {
  1283. switch (/*type*/tagValue[0].pType)
  1284. {
  1285. case TAG_TYPE.TAG_TYPE_BOOL:
  1286. strType += "Boolean";
  1287. break;
  1288. case TAG_TYPE.TAG_TYPE_SINT:
  1289. strType += "SByte";
  1290. break;
  1291. case TAG_TYPE.TAG_TYPE_INT:
  1292. strType += "Int16";
  1293. break;
  1294. case TAG_TYPE.TAG_TYPE_DINT:
  1295. strType += "Int32";
  1296. break;
  1297. case TAG_TYPE.TAG_TYPE_LINT:
  1298. strType += "Int64";
  1299. break;
  1300. case TAG_TYPE.TAG_TYPE_USINT:
  1301. strType += "Byte";
  1302. break;
  1303. case TAG_TYPE.TAG_TYPE_UINT:
  1304. strType += "UInt16";
  1305. break;
  1306. case TAG_TYPE.TAG_TYPE_UDINT:
  1307. strType += "UInt32";
  1308. break;
  1309. case TAG_TYPE.TAG_TYPE_ULINT:
  1310. strType += "UInt64";
  1311. break;
  1312. case TAG_TYPE.TAG_TYPE_REAL:
  1313. strType += "Single";
  1314. break;
  1315. case TAG_TYPE.TAG_TYPE_LREAL:
  1316. strType += "Double";
  1317. break;
  1318. case TAG_TYPE.TAG_TYPE_STRING:
  1319. strType += "String";
  1320. break;
  1321. case TAG_TYPE.TAG_TYPE_BYTE:
  1322. strType += "Byte";
  1323. break;
  1324. case TAG_TYPE.TAG_TYPE_WORD:
  1325. strType += "UInt16";
  1326. break;
  1327. case TAG_TYPE.TAG_TYPE_DWORD:
  1328. strType += "UInt32";
  1329. break;
  1330. case TAG_TYPE.TAG_TYPE_LWORD:
  1331. strType += "UInt64";
  1332. break;
  1333. case TAG_TYPE.TAG_TYPE_STRUCT:
  1334. strType += "STRUCT";
  1335. break;
  1336. case TAG_TYPE.TAG_TYPE_ARRAY:
  1337. strType += "ARRAY";
  1338. break;
  1339. default:
  1340. break;
  1341. }
  1342. pBuf = new byte[tagValue[0].nDataLength];
  1343. unsafe
  1344. {
  1345. byte* memBytePtr = (byte*)tagValue[0].pData.ToPointer();
  1346. for (int j = 0; j < tagValue[0].nDataLength; j++)
  1347. {
  1348. pBuf[j] = memBytePtr[j];
  1349. //string str = "";
  1350. //str += j.ToString() + ": ";
  1351. //str += "0x" + String.Format("{0:X2}", memBytePtr[j]) + "\n";
  1352. }
  1353. }
  1354. DeleteTagListStru(ref tagValue[0], 1); //调用接口释放内存
  1355. }
  1356. }
  1357. else
  1358. {
  1359. return (-10, "元素个数参数错误,必须>0");
  1360. }
  1361. return (0, strType);
  1362. }
  1363. }
  1364. public (int, string) Write_Tag(string strTagName, int nCount, byte[] pBuf)
  1365. {
  1366. lock (m_objLock)
  1367. {
  1368. if (!m_bConnected) return (-1, "未连接");
  1369. string tagName = strTagName;
  1370. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(tagName);
  1371. if (m_nInstanceId <= 0)
  1372. {
  1373. return (-2, "实例ID需大于0");
  1374. }
  1375. if (tagNameUTF8.Length > 255)
  1376. {
  1377. return (-3, "标签名长度超过255字节");
  1378. }
  1379. ushort elementCount = (ushort)nCount;
  1380. if ((pBuf.Length < 1) || (elementCount < 1))
  1381. {
  1382. return (-4, "请求个数必须大于0,请重新输入");
  1383. }
  1384. if (pBuf.Length > 1400)
  1385. {
  1386. return (-5, "标签数据长度超过1400字节,请重新输入");
  1387. }
  1388. int dataLength = pBuf.Length;
  1389. tagTagWriteDataBase[] pTaglist = new tagTagWriteDataBase[1];
  1390. //标签1属性
  1391. pTaglist[0].pName = tagName;
  1392. pTaglist[0].nElementCount = elementCount;
  1393. pTaglist[0].pType = TAG_TYPE.TAG_TYPE_UNDEFINE;
  1394. pTaglist[0].pData = Marshal.AllocHGlobal(1400);
  1395. pTaglist[0].nDataLength = dataLength;
  1396. byte temp = 0;
  1397. for (int i = 0; i < dataLength; ++i)
  1398. {
  1399. temp = pBuf[i];
  1400. Marshal.WriteByte(pTaglist[0].pData + i * sizeof(byte), temp);
  1401. }
  1402. //ERROR_NO errorNo = (ERROR_NO)EipWriteTag(m_nInstanceId, tagName, (int)type, source, dataLength, elementCount, arrayPos/*, strLen*/);
  1403. //ERROR_NO errorNo = (ERROR_NO)EipWriteTagExt(m_nInstanceId, tagName, (int)type, source, dataLength, elementCount);
  1404. ERROR_NO errorNo = EipWriteTagExt2(m_nInstanceId, pTaglist);
  1405. //ERROR_NO errorNo = EipWriteTagRaw(instanceId, pTaglist);
  1406. string strLog = "";
  1407. strLog += "\n写入请求 ";
  1408. if (errorNo != ERROR_NO.SUCCESS)
  1409. {
  1410. strLog += " 失败 标签名:" + tagName + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1411. switch (errorNo)
  1412. {
  1413. case ERROR_NO.ERR_EIP_STOPED:
  1414. strLog += ("协议栈未开启");
  1415. break;
  1416. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1417. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1418. break;
  1419. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1420. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1421. break;
  1422. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1423. strLog += ("达到最大连接数量");
  1424. break;
  1425. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1426. strLog += ("内存溢出,缓冲区已满");
  1427. break;
  1428. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1429. strLog += ("连接的网络地址无效");
  1430. break;
  1431. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1432. strLog += ("连接无响应");
  1433. break;
  1434. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1435. strLog += ("连接响应错误");
  1436. break;
  1437. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1438. strLog += ("目标标签不存在");
  1439. break;
  1440. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1441. strLog += ("标签名超过255字节");
  1442. break;
  1443. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1444. strLog += ("请求数据超限");
  1445. break;
  1446. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1447. strLog += ("响应超时,请检查设备是否离线");
  1448. break;
  1449. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1450. strLog += ("标签名解析错误");
  1451. break;
  1452. case ERROR_NO.ERRR_WRITE_DATASIZE_UNCONSISTENT:
  1453. strLog += ("写入数据长度与标签实际长度不一致");
  1454. break;
  1455. case ERROR_NO.ERRR_SCAN_ERROR:
  1456. strLog += ("扫描标签信息失败");
  1457. break;
  1458. default:
  1459. strLog += ("其他错误");
  1460. break;
  1461. }
  1462. strLog += "\n";
  1463. return (10, strLog);
  1464. }
  1465. else
  1466. {
  1467. return (0, "OK");
  1468. }
  1469. }
  1470. }
  1471. /// <summary>
  1472. /// 标签结构
  1473. /// </summary>
  1474. public struct StructTag
  1475. {
  1476. public string strTagName;
  1477. public Type tTagType;
  1478. public int nCount;
  1479. }
  1480. /// <summary>
  1481. /// 一次读取多个标签
  1482. /// </summary>
  1483. /// <param name="stTagList">多个标签的列表</param>
  1484. /// <param name="pBuf">多个标签的返回值</param>
  1485. /// <returns>函数执行结构值,非零异常,零成功</returns>
  1486. public (int, string) Read_Tags(List<StructTag> stTagList, out byte[][] pBuf)
  1487. {
  1488. pBuf = null;
  1489. string strType = "";
  1490. lock (m_objLock)
  1491. {
  1492. if (!m_bConnected) return (-1, "未连接");
  1493. if (m_nInstanceId <= 0)
  1494. {
  1495. return (-2, "实例ID需大于0");
  1496. }
  1497. if (stTagList == null) return (-3, "标签列表空");
  1498. int nNumOfTags = stTagList.Count;
  1499. if (nNumOfTags < 1) return (-4, "标签列表长度空");
  1500. for (int i = 0; i < nNumOfTags; i++)
  1501. {
  1502. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(stTagList[i].strTagName);
  1503. if (tagNameUTF8.Length > 255)
  1504. {
  1505. return (-5, "标签名长度超过255字节");
  1506. }
  1507. if (stTagList[i].nCount < 1) return (-6, "标签读取长度小于1");
  1508. }
  1509. tagTagReadDataBase[] pTaglist = new tagTagReadDataBase[nNumOfTags];
  1510. for (int i = 0; i < nNumOfTags; i++)
  1511. {
  1512. pTaglist[i].pName = stTagList[i].strTagName;
  1513. pTaglist[i].nElementCount = stTagList[i].nCount;
  1514. }
  1515. tagTagRetValue[] pTagsValue = new tagTagRetValue[nNumOfTags];
  1516. pBuf = new byte[nNumOfTags][];
  1517. if (pBuf == null) return (-7, "分配内存失败,可能内存不足");
  1518. //ERROR_NO errorNo = (ERROR_NO)EipReadTagList(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0]);
  1519. ERROR_NO errorNo = (ERROR_NO)EipReadTagListExt(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0], true);
  1520. //ERROR_NO errorNo = (ERROR_NO)EipReadTagListRaw(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0]);
  1521. string strLog = "";
  1522. strLog += "\n读取请求";
  1523. if (errorNo != ERROR_NO.SUCCESS)
  1524. {
  1525. strLog += " 失败 标签个数:" + nNumOfTags.ToString() + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1526. switch (errorNo)
  1527. {
  1528. case ERROR_NO.ERR_EIP_STOPED:
  1529. strLog += ("协议栈未开启");
  1530. break;
  1531. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1532. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1533. break;
  1534. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1535. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1536. break;
  1537. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1538. strLog += ("达到最大连接数量");
  1539. break;
  1540. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1541. strLog += ("内存溢出,缓冲区已满");
  1542. break;
  1543. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1544. strLog += ("连接的网络地址无效");
  1545. break;
  1546. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1547. strLog += ("连接无响应");
  1548. break;
  1549. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1550. strLog += ("连接响应错误");
  1551. break;
  1552. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1553. strLog += ("目标标签不存在");
  1554. break;
  1555. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1556. strLog += ("标签名超过255字节");
  1557. break;
  1558. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1559. strLog += ("请求数据超限");
  1560. break;
  1561. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1562. strLog += ("响应超时,请检查设备是否离线");
  1563. break;
  1564. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1565. strLog += ("标签名解析错误");
  1566. break;
  1567. case ERROR_NO.ERRR_SCAN_ERROR:
  1568. strLog += ("扫描标签信息失败");
  1569. break;
  1570. default:
  1571. strLog += ("其他错误");
  1572. break;
  1573. }
  1574. strLog += "\n";
  1575. return (-10, strLog);
  1576. }
  1577. else
  1578. {
  1579. for (int i = 0; i < nNumOfTags; i++)
  1580. {
  1581. strType += "\n标签名:" + pTaglist[i].pName + " 类型:";
  1582. switch (pTagsValue[i].pType)
  1583. {
  1584. case TAG_TYPE.TAG_TYPE_BOOL:
  1585. strType += "BOOL";
  1586. break;
  1587. case TAG_TYPE.TAG_TYPE_SINT:
  1588. strType += "SINT";
  1589. break;
  1590. case TAG_TYPE.TAG_TYPE_INT:
  1591. strType += "INT";
  1592. break;
  1593. case TAG_TYPE.TAG_TYPE_DINT:
  1594. strType += "DINT";
  1595. break;
  1596. case TAG_TYPE.TAG_TYPE_LINT:
  1597. strType += "LINT";
  1598. break;
  1599. case TAG_TYPE.TAG_TYPE_USINT:
  1600. strType += "USINT";
  1601. break;
  1602. case TAG_TYPE.TAG_TYPE_UINT:
  1603. strType += "UINT";
  1604. break;
  1605. case TAG_TYPE.TAG_TYPE_UDINT:
  1606. strType += "UDINT";
  1607. break;
  1608. case TAG_TYPE.TAG_TYPE_ULINT:
  1609. strType += "ULINT";
  1610. break;
  1611. case TAG_TYPE.TAG_TYPE_REAL:
  1612. strType += "REAL";
  1613. break;
  1614. case TAG_TYPE.TAG_TYPE_LREAL:
  1615. strType += "LREAL";
  1616. break;
  1617. case TAG_TYPE.TAG_TYPE_STRING:
  1618. strType += "STRING";
  1619. break;
  1620. case TAG_TYPE.TAG_TYPE_BYTE:
  1621. strType += "BYTE";
  1622. break;
  1623. case TAG_TYPE.TAG_TYPE_WORD:
  1624. strType += "WORD";
  1625. break;
  1626. case TAG_TYPE.TAG_TYPE_DWORD:
  1627. strType += "DWORD";
  1628. break;
  1629. case TAG_TYPE.TAG_TYPE_LWORD:
  1630. strType += "LWORD";
  1631. break;
  1632. case TAG_TYPE.TAG_TYPE_STRUCT:
  1633. strType += "STRUCT";
  1634. break;
  1635. case TAG_TYPE.TAG_TYPE_ARRAY:
  1636. strType += "ARRAY";
  1637. break;
  1638. default:
  1639. strType += pTagsValue[i].pType.ToString();
  1640. break;
  1641. }
  1642. strType += " 元素个数:" + pTaglist[i].nElementCount.ToString();
  1643. strType += " 数据长度:" + pTagsValue[i].nDataLength.ToString() + "\n";
  1644. unsafe
  1645. {
  1646. byte* memBytePtr = (byte*)pTagsValue[i].pData.ToPointer();
  1647. pBuf[i] = new byte[pTagsValue[i].nDataLength];
  1648. for (int j = 0; j < pTagsValue[i].nDataLength; j++)
  1649. {
  1650. pBuf[i][j] = memBytePtr[j];
  1651. //string str = "";
  1652. ///str += j.ToString() + ": ";
  1653. //str += "0x" + String.Format("{0:X2}", memBytePtr[j]) + "\n";
  1654. }
  1655. }
  1656. }
  1657. }
  1658. DeleteTagListStru(ref pTagsValue[0], nNumOfTags); //调用接口释放内存
  1659. return (0, strType);
  1660. }
  1661. }
  1662. /// <summary>
  1663. /// 一次写多个标签
  1664. /// </summary>
  1665. /// <param name="TagList">将写入的标签列表</param>
  1666. /// <param name="ObjList">与标签列表对应的值对象</param>
  1667. /// <returns></returns>
  1668. public (int, string) Write_Tags(List<StructTag> TagList, List<Object> ObjList)
  1669. {
  1670. int size = 0;
  1671. byte[] pBuf = null;
  1672. int nRet = 0;
  1673. string strRet = "";
  1674. if (!m_bConnected) return (-1, "未连接");
  1675. if (m_nInstanceId <= 0) return (-2, "实例ID需大于0");
  1676. if (ObjList.Count != TagList.Count) return (-3, "标签列表和数据列表不一致");
  1677. int nLen = TagList.Count;
  1678. int nNumOfTags = TagList.Count;
  1679. tagTagWriteDataBase[] pTaglist = new tagTagWriteDataBase[nNumOfTags];
  1680. try
  1681. {
  1682. for (int i = 0; i < nLen; i++)
  1683. {
  1684. if (TagList[i].strTagName.Length > 255) return (-4, "标签名称长度超过255字节");
  1685. if (TagList[i].tTagType == null) return (-5, "标签类型不能空");
  1686. //标签属性
  1687. pTaglist[i].pName = TagList[i].strTagName;
  1688. pTaglist[i].nElementCount = TagList[i].nCount;
  1689. pTaglist[i].pType = TAG_TYPE.TAG_TYPE_UNDEFINE;
  1690. pTaglist[i].pData = Marshal.AllocHGlobal(1400);
  1691. //标签写入的数据
  1692. size = 0;
  1693. string str = TagList[i].tTagType.Name;
  1694. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  1695. bool containsAny = substrings.Any(substring => str.Contains(substring));
  1696. if (containsAny)
  1697. {
  1698. Type type = ObjList[i].GetType();
  1699. if (str != type.Name) return (120, "变量类型不一致");
  1700. }
  1701. if (str == "String")
  1702. {
  1703. string data = ObjList[i] as string;
  1704. pBuf = System.Text.Encoding.Default.GetBytes(data);
  1705. size = pBuf.Length;
  1706. if (size > 1400)
  1707. {
  1708. return (110, "数据长度超过1400字节,请重新输入");
  1709. }
  1710. }
  1711. else
  1712. {
  1713. if (TagList[i].tTagType.Name == "Boolean")
  1714. {
  1715. pBuf = new byte[1];
  1716. Type targetType = TagList[i].tTagType;
  1717. if ((bool)Convert.ChangeType(ObjList[i], targetType))
  1718. {
  1719. pBuf[0] = 1;
  1720. }
  1721. else
  1722. {
  1723. pBuf[0] = 0;
  1724. }
  1725. size = 1;
  1726. }
  1727. else
  1728. {
  1729. size = Marshal.SizeOf(TagList[i].tTagType);
  1730. pBuf = StructToBytes(ObjList[i], size);
  1731. }
  1732. }
  1733. //填充数据
  1734. for (int j = 0; j < size; j++)
  1735. {
  1736. Marshal.WriteByte(pTaglist[i].pData + j * sizeof(byte), pBuf[j]);
  1737. }
  1738. pTaglist[i].nDataLength = size;
  1739. }
  1740. ERROR_NO errorNo = ERROR_NO.SUCCESS;
  1741. lock (m_objLock)
  1742. {
  1743. //errorNo = EipWriteTagList(m_nInstanceId, nNumOfTags, pTaglist);
  1744. errorNo = EipWriteTagListExt(m_nInstanceId, nNumOfTags, pTaglist, true);
  1745. //errorNo = EipWriteTagListRaw(m_nInstanceId, nNumOfTags, pTaglist);
  1746. }
  1747. string strLog = "";
  1748. strLog += "\n写入请求";
  1749. if (errorNo != ERROR_NO.SUCCESS)
  1750. {
  1751. strLog += " 失败 标签个数:" + nNumOfTags.ToString() + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1752. switch (errorNo)
  1753. {
  1754. case ERROR_NO.ERR_EIP_STOPED:
  1755. strLog += ("协议栈未开启");
  1756. break;
  1757. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1758. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1759. break;
  1760. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1761. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1762. break;
  1763. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1764. strLog += ("达到最大连接数量");
  1765. break;
  1766. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1767. strLog += ("内存溢出,缓冲区已满");
  1768. break;
  1769. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1770. strLog += ("连接的网络地址无效");
  1771. break;
  1772. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1773. strLog += ("连接无响应");
  1774. break;
  1775. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1776. strLog += ("连接响应错误");
  1777. break;
  1778. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1779. strLog += ("目标标签不存在");
  1780. break;
  1781. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1782. strLog += ("标签名超过255字节");
  1783. break;
  1784. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1785. strLog += ("请求数据超限");
  1786. break;
  1787. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1788. strLog += ("响应超时,请检查设备是否离线");
  1789. break;
  1790. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1791. strLog += ("标签名解析错误");
  1792. break;
  1793. case ERROR_NO.ERRR_WRITE_DATASIZE_UNCONSISTENT:
  1794. strLog += ("写入数据长度与标签实际长度不一致");
  1795. break;
  1796. case ERROR_NO.ERRR_SCAN_ERROR:
  1797. strLog += ("扫描标签信息失败");
  1798. break;
  1799. default:
  1800. strLog += ("其他错误");
  1801. break;
  1802. }
  1803. strLog += "\n";
  1804. strRet = strLog;
  1805. nRet = -10;
  1806. }
  1807. else
  1808. {
  1809. //成功
  1810. strRet = "OK";
  1811. nRet = 0;
  1812. }
  1813. }
  1814. catch (Exception ex)
  1815. {
  1816. nRet = 120;
  1817. strRet = ex.ToString();
  1818. }
  1819. finally
  1820. {
  1821. for (int i = 0; i < nLen; i++)
  1822. {
  1823. if (pTaglist[i].pData != ((IntPtr)0))
  1824. {
  1825. Marshal.FreeHGlobal(pTaglist[i].pData);
  1826. pTaglist[i].pData = (IntPtr)0;
  1827. }
  1828. }
  1829. }
  1830. return (nRet, strRet);
  1831. }
  1832. /// <summary>
  1833. /// 一次读取Bool标签或Bool数组标签
  1834. /// </summary>
  1835. /// <param name="strTagName">标签的名称</param>
  1836. /// <param name="nCount">读取的标签个数</param>
  1837. /// <param name="boolBuf">相应标签的返回值</param>
  1838. /// <returns>函数返回结果</returns>
  1839. public (int, string) Read_Bool_Tag(string strTagName, int nCount, out bool[] boolBuf)
  1840. {
  1841. byte[] pBuf = null;
  1842. boolBuf = null;
  1843. int nRet = 0;
  1844. string strRet = "";
  1845. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1846. if (nRet != 0) return (nRet, strRet);
  1847. return Parse_Bool_Tag(pBuf, out boolBuf);
  1848. }
  1849. /// <summary>
  1850. /// 一次写入Bool标签或Bool数组标签
  1851. /// </summary>
  1852. /// <param name="strTagName">标签的名称</param>
  1853. /// <param name="nCount">标签个数</param>
  1854. /// <param name="boolBuf">相应标签的写入值</param>
  1855. /// <returns>函数返回结果</returns>
  1856. public (int, string) Write_Bool_Tag(string strTagName, int nCount, bool[] boolBuf)
  1857. {
  1858. byte[] pBuf = null;
  1859. int nRet = 0;
  1860. string strRet = "";
  1861. pBuf = BoolToBytes(boolBuf);
  1862. if (pBuf == null) return (1, "缓存区空");
  1863. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1864. return (nRet, strRet);
  1865. }
  1866. //将转换为Byte数组
  1867. public static byte[] BoolToBytes(bool[] boolBuf)
  1868. {
  1869. if (boolBuf==null) return null;
  1870. int nNum = 0;
  1871. nNum = boolBuf.Length;
  1872. if (nNum < 1) return null;
  1873. byte[] bytes = new byte[nNum];
  1874. for (int i = 0; i < nNum; i++)
  1875. {
  1876. if (boolBuf[i])
  1877. bytes[i] = 1;
  1878. else
  1879. bytes[i] = 0;
  1880. }
  1881. return bytes;
  1882. }
  1883. public (int, string) Parse_Bool_Tag(byte[] pBuf, out bool[] boolBuf)
  1884. {
  1885. boolBuf = null;
  1886. int nNum = 0;
  1887. nNum = pBuf.Length;
  1888. if (nNum < 1) return (1, "Parse Failed");
  1889. boolBuf = new bool[nNum];
  1890. for (int i = 0; i < nNum; i++)
  1891. {
  1892. byte[] databuf = new byte[1] {0};
  1893. databuf[0] = pBuf[i];
  1894. bool iTemp = BitConverter.ToBoolean(databuf, 0);
  1895. boolBuf[i] = iTemp;
  1896. }
  1897. return (0, "OK");
  1898. }
  1899. public (int, string) Read_Byte_Tag(string strTagName, int nCount, out byte[] pBuf)
  1900. {
  1901. return Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1902. }
  1903. public (int, string) Write_Byte_Tag(string strTagName, int nCount, byte[] pBuf)
  1904. {
  1905. return Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1906. }
  1907. public (int, string) Read_SInt_Tag(string strTagName, int nCount, out sbyte[] sintBuf)
  1908. {
  1909. byte[] pBuf = null;
  1910. sintBuf = null;
  1911. int nRet = 0;
  1912. string strRet = "";
  1913. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1914. if (nRet != 0) return (nRet, strRet);
  1915. return Parse_SInt_Tag(pBuf, out sintBuf);
  1916. }
  1917. public (int, string) Write_SInt_Tag(string strTagName, int nCount, sbyte[] DataBuf)
  1918. {
  1919. byte[] pBuf = null;
  1920. int nRet = 0;
  1921. string strRet = "";
  1922. pBuf = SByteToBytes(DataBuf);
  1923. if (pBuf == null) return (1, "pBuf is Null");
  1924. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1925. return (nRet, strRet);
  1926. }
  1927. //将转换为Byte数组
  1928. public static byte[] SByteToBytes(sbyte[] DataBuf)
  1929. {
  1930. if (DataBuf == null || DataBuf.Length <= 0) return null;
  1931. int nNum = 0;
  1932. nNum = DataBuf.Length;
  1933. if (nNum < 1) return null;
  1934. byte[] bytes = new byte[nNum];
  1935. for (int i = 0; i < nNum; i++)
  1936. {
  1937. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  1938. bytes[i] = databuf[0];
  1939. }
  1940. return bytes;
  1941. }
  1942. public (int, string) Parse_SInt_Tag(byte[] pBuf, out sbyte[] sintBuf)
  1943. {
  1944. sintBuf = null;
  1945. int nNum = 0;
  1946. nNum = pBuf.Length;
  1947. if (nNum < 1) return (1, "Parse Failed");
  1948. sintBuf = new sbyte[nNum];
  1949. for (int i = 0; i < nNum; i++)
  1950. {
  1951. sintBuf[i] = (sbyte)pBuf[i];
  1952. }
  1953. return (0, "OK");
  1954. }
  1955. public (int, string) Read_String_Tag(string strTagName, int nCount, out string strBuf)
  1956. {
  1957. int nRet=0;
  1958. string strRet = "";
  1959. byte[] pBuf = null;
  1960. strBuf = "";
  1961. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1962. if (nRet == 0)
  1963. strBuf = System.Text.Encoding.UTF8.GetString(pBuf);
  1964. return (nRet, strRet);
  1965. }
  1966. public (int, string) Write_String_Tag(string strTagName, int nCount, string strBuf)
  1967. {
  1968. int nRet = 0;
  1969. string strRet = "";
  1970. byte[] pBuf = null;
  1971. if (string.IsNullOrEmpty(strBuf)) return (1, "string is null");
  1972. pBuf = System.Text.Encoding.UTF8.GetBytes(strBuf);
  1973. if (pBuf == null || pBuf.Length == 0 ) return (2, "pBuf is null");
  1974. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1975. return (nRet, strRet);
  1976. }
  1977. public (int, string) Parse_String_Tag(byte[] pBuf, out string strBuf)
  1978. {
  1979. int nRet = 0;
  1980. string strRet = "";
  1981. strBuf = "";
  1982. strBuf = System.Text.Encoding.UTF8.GetString(pBuf);
  1983. return (nRet, strRet);
  1984. }
  1985. public (int, string) Read_Word_Tag(string strTagName, int nCount, out ushort[] wordBuf)
  1986. {
  1987. return Read_UInt_Tag(strTagName, nCount, out wordBuf);
  1988. }
  1989. public (int, string) Write_Word_Tag(string strTagName, int nCount, ushort[] wordBuf)
  1990. {
  1991. return Write_UInt_Tag(strTagName, nCount, wordBuf);
  1992. }
  1993. public (int, string) Read_DWord_Tag(string strTagName, int nCount, out uint[] dwordBuf)
  1994. {
  1995. return Read_UDInt_Tag(strTagName, nCount, out dwordBuf);
  1996. }
  1997. public (int, string) Write_DWord_Tag(string strTagName, int nCount, uint[] dwordBuf)
  1998. {
  1999. return Write_UDInt_Tag(strTagName, nCount, dwordBuf);
  2000. }
  2001. public (int, string) Read_LWord_Tag(string strTagName, int nCount, out ulong[] lwordBuf)
  2002. {
  2003. return Read_ULInt_Tag(strTagName, nCount, out lwordBuf);
  2004. }
  2005. public (int, string) Write_LWord_Tag(string strTagName, int nCount, ulong[] lwordBuf)
  2006. {
  2007. return Write_ULInt_Tag(strTagName, nCount, lwordBuf);
  2008. }
  2009. /// <summary>
  2010. /// read 16bit int
  2011. /// </summary>
  2012. /// <param name="strTagName"></param>
  2013. /// <param name="nCount"></param>
  2014. /// <param name="intBuf"></param>
  2015. /// <returns></returns>
  2016. public (int, string) Read_Int_Tag(string strTagName, int nCount, out short[] intBuf)
  2017. {
  2018. byte[] pBuf = null;
  2019. intBuf = null;
  2020. int nRet=0;
  2021. string strRet = "";
  2022. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2023. if (nRet != 0) return (nRet, strRet);
  2024. return Parse_Int_Tag(pBuf, out intBuf);
  2025. }
  2026. public (int, string) Parse_Int_Tag(byte[] pBuf, out short[] intBuf)
  2027. {
  2028. intBuf = null;
  2029. int nNum = 0;
  2030. nNum = pBuf.Length / 2;
  2031. if (nNum < 1) return (1, "Parse Failed");
  2032. intBuf = new short[nNum];
  2033. for (int i = 0; i < nNum; i++)
  2034. {
  2035. byte[] databuf = new byte[2] { 0, 0 };
  2036. databuf[0] = pBuf[i * 2];
  2037. databuf[1] = pBuf[i * 2 + 1];
  2038. short iTemp = BitConverter.ToInt16(databuf, 0);
  2039. intBuf[i] = iTemp;
  2040. }
  2041. return (0, "OK");
  2042. }
  2043. public (int, string) Write_Int_Tag(string strTagName, int nCount, short[] DataBuf)
  2044. {
  2045. byte[] pBuf = null;
  2046. int nRet = 0;
  2047. string strRet = "";
  2048. pBuf = ShortToBytes(DataBuf);
  2049. if (pBuf == null ) return (1, "pBuf is Null");
  2050. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2051. return (nRet, strRet);
  2052. }
  2053. //将转换为Byte数组
  2054. public static byte[] ShortToBytes(short[] DataBuf)
  2055. {
  2056. if (DataBuf == null || DataBuf.Length<=0) return null;
  2057. int nNum = 0;
  2058. //int size = Marshal.SizeOf(typeof(short));
  2059. //int size = sizeof(short);
  2060. nNum = DataBuf.Length;
  2061. if (nNum < 1) return null;
  2062. byte[] bytes = new byte[nNum*2];
  2063. for (int i = 0; i < nNum; i++)
  2064. {
  2065. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2066. bytes[i * 2] = databuf[0];
  2067. bytes[i * 2 + 1] = databuf[1];
  2068. }
  2069. return bytes;
  2070. }
  2071. /// <summary>
  2072. /// 16bit uint
  2073. /// </summary>
  2074. /// <param name="strTagName"></param>
  2075. /// <param name="nCount"></param>
  2076. /// <param name="uintBuf"></param>
  2077. /// <returns></returns>
  2078. public (int, string) Read_UInt_Tag(string strTagName, int nCount, out UInt16[] uintBuf)
  2079. {
  2080. byte[] pBuf = null;
  2081. uintBuf = null;
  2082. int nRet = 0;
  2083. string strRet = "";
  2084. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2085. if (nRet != 0) return (nRet, strRet);
  2086. return Parse_UInt_Tag(pBuf, out uintBuf);
  2087. }
  2088. public (int, string) Write_UInt_Tag(string strTagName, int nCount, ushort[] DataBuf)
  2089. {
  2090. byte[] pBuf = null;
  2091. int nRet = 0;
  2092. string strRet = "";
  2093. pBuf = UShortToBytes(DataBuf);
  2094. if (pBuf == null) return (1, "pBuf is Null");
  2095. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2096. return (nRet, strRet);
  2097. }
  2098. //将转换为Byte数组
  2099. public static byte[] UShortToBytes(ushort[] DataBuf)
  2100. {
  2101. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2102. int nNum = 0;
  2103. //int size = Marshal.SizeOf(typeof(short));
  2104. //int size = sizeof(short);
  2105. nNum = DataBuf.Length;
  2106. if (nNum < 1) return null;
  2107. byte[] bytes = new byte[nNum*2];
  2108. for (int i = 0; i < nNum; i++)
  2109. {
  2110. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2111. bytes[i * 2] = databuf[0];
  2112. bytes[i * 2 + 1] = databuf[1];
  2113. }
  2114. return bytes;
  2115. }
  2116. public (int, string) Parse_UInt_Tag(byte[] pBuf, out UInt16[] uintBuf)
  2117. {
  2118. uintBuf = null;
  2119. int nNum = 0;
  2120. nNum = pBuf.Length / 2;
  2121. if (nNum < 1) return (1, "Parse Failed");
  2122. uintBuf = new UInt16[nNum];
  2123. for (int i = 0; i < nNum; i++)
  2124. {
  2125. byte[] databuf = new byte[2] { 0, 0 };
  2126. databuf[0] = pBuf[i * 2];
  2127. databuf[1] = pBuf[i * 2 + 1];
  2128. UInt16 iTemp = BitConverter.ToUInt16(databuf, 0);
  2129. uintBuf[i] = iTemp;
  2130. }
  2131. return (0, "OK");
  2132. }
  2133. /// <summary>
  2134. /// 32bits int
  2135. /// </summary>
  2136. /// <param name="strTagName"></param>
  2137. /// <param name="nCount"></param>
  2138. /// <param name="intBuf"></param>
  2139. /// <returns></returns>
  2140. public (int, string) Read_DInt_Tag(string strTagName, int nCount, out int[] intBuf)
  2141. {
  2142. byte[] pBuf = null;
  2143. intBuf = null;
  2144. int nRet = 0;
  2145. string strRet = "";
  2146. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2147. if (nRet != 0) return (nRet, strRet);
  2148. return Parse_DInt_Tag(pBuf, out intBuf);
  2149. }
  2150. public (int, string) Write_DInt_Tag(string strTagName, int nCount, int[] DataBuf)
  2151. {
  2152. byte[] pBuf = null;
  2153. int nRet = 0;
  2154. string strRet = "";
  2155. pBuf = DIntToBytes(DataBuf);
  2156. if (pBuf == null) return (1, "pBuf is Null");
  2157. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2158. return (nRet, strRet);
  2159. }
  2160. //将转换为Byte数组
  2161. public static byte[] DIntToBytes(int[] DataBuf)
  2162. {
  2163. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2164. int nNum = 0;
  2165. nNum = DataBuf.Length;
  2166. if (nNum < 1) return null;
  2167. byte[] bytes = new byte[nNum*4];
  2168. for (int i = 0; i < nNum; i++)
  2169. {
  2170. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2171. bytes[i * 4] = databuf[0];
  2172. bytes[i * 4 + 1] = databuf[1];
  2173. bytes[i * 4 + 2] = databuf[2];
  2174. bytes[i * 4 + 3] = databuf[3];
  2175. }
  2176. return bytes;
  2177. }
  2178. public (int, string) Parse_DInt_Tag(byte[] pBuf, out int[] intBuf)
  2179. {
  2180. intBuf = null;
  2181. int nNum = 0;
  2182. nNum = pBuf.Length / 4;
  2183. if (nNum < 1) return (1, "Parse Failed");
  2184. intBuf = new int[nNum];
  2185. for (int i = 0; i < nNum; i++)
  2186. {
  2187. byte[] databuf = new byte[4] { 0, 0, 0, 0 };
  2188. databuf[0] = pBuf[i * 4];
  2189. databuf[1] = pBuf[i * 4 + 1];
  2190. databuf[2] = pBuf[i * 4 + 2];
  2191. databuf[3] = pBuf[i * 4 + 3];
  2192. int iTemp = BitConverter.ToInt32(databuf, 0);
  2193. intBuf[i] = iTemp;
  2194. }
  2195. return (0, "OK");
  2196. }
  2197. /// <summary>
  2198. /// 无符号32位整数
  2199. /// </summary>
  2200. /// <param name="strTagName"></param>
  2201. /// <param name="nCount"></param>
  2202. /// <param name="intBuf"></param>
  2203. /// <returns></returns>
  2204. public (int, string) Read_UDInt_Tag(string strTagName, int nCount, out uint[] uintBuf)
  2205. {
  2206. byte[] pBuf = null;
  2207. uintBuf = null;
  2208. int nRet = 0;
  2209. string strRet = "";
  2210. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2211. if (nRet != 0) return (nRet, strRet);
  2212. return Parse_UDInt_Tag(pBuf, out uintBuf);
  2213. }
  2214. public (int, string) Write_UDInt_Tag(string strTagName, int nCount, uint[] DataBuf)
  2215. {
  2216. byte[] pBuf = null;
  2217. int nRet = 0;
  2218. string strRet = "";
  2219. pBuf = UDIntToBytes(DataBuf);
  2220. if (pBuf == null) return (1, "pBuf is Null");
  2221. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2222. return (nRet, strRet);
  2223. }
  2224. //将转换为Byte数组
  2225. public static byte[] UDIntToBytes(uint[] DataBuf)
  2226. {
  2227. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2228. int nNum = 0;
  2229. nNum = DataBuf.Length;
  2230. if (nNum < 1) return null;
  2231. byte[] bytes = new byte[nNum * 4];
  2232. for (int i = 0; i < nNum; i++)
  2233. {
  2234. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2235. bytes[i * 4] = databuf[0];
  2236. bytes[i * 4 + 1] = databuf[1];
  2237. bytes[i * 4 + 2] = databuf[2];
  2238. bytes[i * 4 + 3] = databuf[3];
  2239. }
  2240. return bytes;
  2241. }
  2242. public (int, string) Parse_UDInt_Tag(byte[] pBuf, out uint[] uintBuf)
  2243. {
  2244. uintBuf = null;
  2245. int nNum = 0;
  2246. nNum = pBuf.Length / 4;
  2247. if (nNum < 1) return (1, "Parse Failed");
  2248. uintBuf = new uint[nNum];
  2249. for (int i = 0; i < nNum; i++)
  2250. {
  2251. byte[] databuf = new byte[4] { 0, 0, 0, 0 };
  2252. databuf[0] = pBuf[i * 4];
  2253. databuf[1] = pBuf[i * 4 + 1];
  2254. databuf[2] = pBuf[i * 4 + 2];
  2255. databuf[3] = pBuf[i * 4 + 3];
  2256. uint iTemp = BitConverter.ToUInt32(databuf, 0);
  2257. uintBuf[i] = iTemp;
  2258. }
  2259. return (0, "OK");
  2260. }
  2261. public (int, string) Read_LInt_Tag(string strTagName, int nCount, out long[] longBuf)
  2262. {
  2263. byte[] pBuf = null;
  2264. longBuf = null;
  2265. int nRet = 0;
  2266. string strRet = "";
  2267. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2268. if (nRet != 0) return (nRet, strRet);
  2269. return Parse_LInt_Tag(pBuf, out longBuf);
  2270. }
  2271. public (int, string) Write_LInt_Tag(string strTagName, int nCount, long[] DataBuf)
  2272. {
  2273. byte[] pBuf = null;
  2274. int nRet = 0;
  2275. string strRet = "";
  2276. pBuf = LIntToBytes(DataBuf);
  2277. if (pBuf == null) return (1, "pBuf is Null");
  2278. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2279. return (nRet, strRet);
  2280. }
  2281. //将转换为Byte数组
  2282. public static byte[] LIntToBytes(long[] DataBuf)
  2283. {
  2284. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2285. int nNum = 0;
  2286. nNum = DataBuf.Length;
  2287. if (nNum < 1) return null;
  2288. byte[] bytes = new byte[nNum * 8];
  2289. for (int i = 0; i < nNum; i++)
  2290. {
  2291. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2292. bytes[i * 4] = databuf[0];
  2293. bytes[i * 4 + 1] = databuf[1];
  2294. bytes[i * 4 + 2] = databuf[2];
  2295. bytes[i * 4 + 3] = databuf[3];
  2296. bytes[i * 4 + 4] = databuf[4];
  2297. bytes[i * 4 + 5] = databuf[5];
  2298. bytes[i * 4 + 6] = databuf[6];
  2299. bytes[i * 4 + 7] = databuf[7];
  2300. }
  2301. return bytes;
  2302. }
  2303. public (int, string) Parse_LInt_Tag(byte[] pBuf, out long[] longBuf)
  2304. {
  2305. longBuf = null;
  2306. int nNum = 0;
  2307. nNum = pBuf.Length / 8;
  2308. if (nNum < 1) return (1, "Parse Failed");
  2309. longBuf = new long[nNum];
  2310. for (int i = 0; i < nNum; i++)
  2311. {
  2312. byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
  2313. databuf[0] = pBuf[i * 4];
  2314. databuf[1] = pBuf[i * 4 + 1];
  2315. databuf[2] = pBuf[i * 4 + 2];
  2316. databuf[3] = pBuf[i * 4 + 3];
  2317. databuf[4] = pBuf[i * 4 + 4];
  2318. databuf[5] = pBuf[i * 4 + 5];
  2319. databuf[6] = pBuf[i * 4 + 6];
  2320. databuf[7] = pBuf[i * 4 + 7];
  2321. long iTemp = BitConverter.ToInt64(databuf, 0);
  2322. longBuf[i] = iTemp;
  2323. }
  2324. return (0, "OK");
  2325. }
  2326. /// <summary>
  2327. /// 无符号64整数
  2328. /// </summary>
  2329. /// <param name="strTagName"></param>
  2330. /// <param name="nCount"></param>
  2331. /// <param name="ulongBuf"></param>
  2332. /// <returns></returns>
  2333. public (int, string) Read_ULInt_Tag(string strTagName, int nCount, out ulong[] ulongBuf)
  2334. {
  2335. byte[] pBuf = null;
  2336. ulongBuf = null;
  2337. int nRet = 0;
  2338. string strRet = "";
  2339. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2340. if (nRet != 0) return (nRet, strRet);
  2341. return Parse_ULInt_Tag(pBuf, out ulongBuf);
  2342. }
  2343. public (int, string) Write_ULInt_Tag(string strTagName, int nCount, ulong[] DataBuf)
  2344. {
  2345. byte[] pBuf = null;
  2346. int nRet = 0;
  2347. string strRet = "";
  2348. pBuf = ULIntToBytes(DataBuf);
  2349. if (pBuf == null) return (1, "pBuf is Null");
  2350. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2351. return (nRet, strRet);
  2352. }
  2353. //将转换为Byte数组
  2354. public static byte[] ULIntToBytes(ulong[] DataBuf)
  2355. {
  2356. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2357. int nNum = 0;
  2358. nNum = DataBuf.Length;
  2359. if (nNum < 1) return null;
  2360. byte[] bytes = new byte[nNum * 8];
  2361. for (int i = 0; i < nNum; i++)
  2362. {
  2363. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2364. bytes[i * 4] = databuf[0];
  2365. bytes[i * 4 + 1] = databuf[1];
  2366. bytes[i * 4 + 2] = databuf[2];
  2367. bytes[i * 4 + 3] = databuf[3];
  2368. bytes[i * 4 + 4] = databuf[4];
  2369. bytes[i * 4 + 5] = databuf[5];
  2370. bytes[i * 4 + 6] = databuf[6];
  2371. bytes[i * 4 + 7] = databuf[7];
  2372. }
  2373. return bytes;
  2374. }
  2375. public (int, string) Parse_ULInt_Tag(byte[] pBuf, out ulong[] ulongBuf)
  2376. {
  2377. ulongBuf = null;
  2378. int nNum = 0;
  2379. nNum = pBuf.Length / 8;
  2380. if (nNum < 1) return (1, "Parse Failed");
  2381. ulongBuf = new ulong[nNum];
  2382. for (int i = 0; i < nNum; i++)
  2383. {
  2384. byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
  2385. databuf[0] = pBuf[i * 4];
  2386. databuf[1] = pBuf[i * 4 + 1];
  2387. databuf[2] = pBuf[i * 4 + 2];
  2388. databuf[3] = pBuf[i * 4 + 3];
  2389. databuf[4] = pBuf[i * 4 + 4];
  2390. databuf[5] = pBuf[i * 4 + 5];
  2391. databuf[6] = pBuf[i * 4 + 6];
  2392. databuf[7] = pBuf[i * 4 + 7];
  2393. ulong iTemp = BitConverter.ToUInt64(databuf, 0);
  2394. ulongBuf[i] = iTemp;
  2395. }
  2396. return (0, "OK");
  2397. }
  2398. public (int, string) Read_Real_Tag(string strTagName, int nCount, out float[] floatBuf)
  2399. {
  2400. floatBuf = null;
  2401. byte[] pBuf = null;
  2402. int nRet = 0;
  2403. string strRet = "";
  2404. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2405. if (nRet != 0) return (nRet, strRet);
  2406. return Parse_Real_Tag(pBuf, out floatBuf);
  2407. }
  2408. public (int, string) Write_Real_Tag(string strTagName, int nCount, float[] DataBuf)
  2409. {
  2410. byte[] pBuf = null;
  2411. int nRet = 0;
  2412. string strRet = "";
  2413. pBuf = RealToBytes(DataBuf);
  2414. if (pBuf == null) return (1, "pBuf is Null");
  2415. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2416. return (nRet, strRet);
  2417. }
  2418. //将转换为Byte数组
  2419. public static byte[] RealToBytes(float[] DataBuf)
  2420. {
  2421. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2422. int nNum = 0;
  2423. nNum = DataBuf.Length;
  2424. if (nNum < 1) return null;
  2425. byte[] bytes = new byte[nNum * 4];
  2426. for (int i = 0; i < nNum; i++)
  2427. {
  2428. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2429. bytes[i * 4] = databuf[0];
  2430. bytes[i * 4 + 1] = databuf[1];
  2431. bytes[i * 4 + 2] = databuf[2];
  2432. bytes[i * 4 + 3] = databuf[3];
  2433. }
  2434. return bytes;
  2435. }
  2436. public (int, string) Parse_Real_Tag(byte[] pBuf, out float[] floatBuf)
  2437. {
  2438. floatBuf = null;
  2439. int nNum = 0;
  2440. nNum = pBuf.Length / 4;
  2441. floatBuf = new float[nNum];
  2442. if (nNum < 1) return (1, "Parse Failed");
  2443. for (int i = 0; i < nNum; i++)
  2444. {
  2445. byte[] databuf = new byte[4] { 0, 0, 0, 0 };
  2446. databuf[0] = pBuf[i * 4];
  2447. databuf[1] = pBuf[i * 4 + 1];
  2448. databuf[2] = pBuf[i * 4 + 2];
  2449. databuf[3] = pBuf[i * 4 + 3];
  2450. float fTemp = BitConverter.ToSingle(databuf, 0);
  2451. floatBuf[i] = fTemp;
  2452. }
  2453. return (0, "OK");
  2454. }
  2455. public (int, string) Read_LReal_Tag(string strTagName, int nCount, out double[] doubleBuf)
  2456. {
  2457. doubleBuf = null;
  2458. byte[] pBuf = null;
  2459. int nRet = 0;
  2460. string strRet = "";
  2461. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2462. if (nRet != 0) return (nRet, strRet);
  2463. return Parse_LReal_Tag(pBuf, out doubleBuf);
  2464. }
  2465. public (int, string) Write_LReal_Tag(string strTagName, int nCount, double[] DataBuf)
  2466. {
  2467. byte[] pBuf = null;
  2468. int nRet = 0;
  2469. string strRet = "";
  2470. pBuf = LRealToBytes(DataBuf);
  2471. if (pBuf == null) return (1, "pBuf is Null");
  2472. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2473. return (nRet, strRet);
  2474. }
  2475. //将转换为Byte数组
  2476. public static byte[] LRealToBytes(double[] DataBuf)
  2477. {
  2478. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2479. int nNum = 0;
  2480. nNum = DataBuf.Length;
  2481. if (nNum < 1) return null;
  2482. byte[] bytes = new byte[nNum * 8];
  2483. for (int i = 0; i < nNum; i++)
  2484. {
  2485. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2486. bytes[i * 4] = databuf[0];
  2487. bytes[i * 4 + 1] = databuf[1];
  2488. bytes[i * 4 + 2] = databuf[2];
  2489. bytes[i * 4 + 3] = databuf[3];
  2490. bytes[i * 4 + 4] = databuf[4];
  2491. bytes[i * 4 + 5] = databuf[5];
  2492. bytes[i * 4 + 6] = databuf[6];
  2493. bytes[i * 4 + 7] = databuf[7];
  2494. }
  2495. return bytes;
  2496. }
  2497. public (int, string) Parse_LReal_Tag(byte[] pBuf, out double[] doubleBuf)
  2498. {
  2499. doubleBuf = null;
  2500. int nNum = 0;
  2501. nNum = pBuf.Length / 8;
  2502. if (nNum < 1) return (1, "Parse Failed");
  2503. doubleBuf = new double[nNum];
  2504. for (int i = 0; i < nNum; i++)
  2505. {
  2506. byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
  2507. databuf[0] = pBuf[i * 8];
  2508. databuf[1] = pBuf[i * 8 + 1];
  2509. databuf[2] = pBuf[i * 8 + 2];
  2510. databuf[3] = pBuf[i * 8 + 3];
  2511. databuf[4] = pBuf[i * 8 + 4];
  2512. databuf[5] = pBuf[i * 8 + 5];
  2513. databuf[6] = pBuf[i * 8 + 6];
  2514. databuf[7] = pBuf[i * 8 + 7];
  2515. double dTemp = BitConverter.ToDouble(databuf, 0);
  2516. doubleBuf[i] = dTemp;
  2517. }
  2518. return (0, "OK");
  2519. }
  2520. #region 对象与字节数组转化
  2521. //将结构体类型转换为Byte数组
  2522. public static byte[] StructToBytes(object structObj, int size)
  2523. {
  2524. byte[] bytes = new byte[size];
  2525. IntPtr structPtr = Marshal.AllocHGlobal(size);
  2526. try
  2527. {
  2528. //将结构体拷到分配好的内存空间
  2529. Marshal.StructureToPtr(structObj, structPtr, false);
  2530. //从内存空间拷贝到byte 数组
  2531. Marshal.Copy(structPtr, bytes, 0, size);
  2532. }
  2533. finally
  2534. {
  2535. //释放内存空间
  2536. Marshal.FreeHGlobal(structPtr);
  2537. }
  2538. return bytes;
  2539. }
  2540. //将Byte转换为结构体类型
  2541. public static object ByteToStruct(byte[] bytes, Type type)
  2542. {
  2543. int size = Marshal.SizeOf(type);
  2544. if (type.Name == "Boolean") size = 1;
  2545. if (size > bytes.Length)
  2546. {
  2547. return null;
  2548. }
  2549. //分配结构体内存空间
  2550. IntPtr structPtr = Marshal.AllocHGlobal(size);
  2551. object obj = null;
  2552. try
  2553. {
  2554. //将byte数组拷贝到分配好的内存空间
  2555. Marshal.Copy(bytes, 0, structPtr, size);
  2556. //将内存空间转换为目标结构体
  2557. obj = Marshal.PtrToStructure(structPtr, type);
  2558. }
  2559. finally
  2560. {
  2561. //释放内存空间
  2562. Marshal.FreeHGlobal(structPtr);
  2563. }
  2564. return obj;
  2565. }
  2566. //将Byte转换为结构体类型
  2567. public static Object ByteToStruct2(byte[] bytes, Type type)
  2568. {
  2569. int size = Marshal.SizeOf(type);
  2570. if (type.Name == "Boolean") size = 1;
  2571. if (size > bytes.Length)
  2572. {
  2573. return null;
  2574. }
  2575. //分配结构体内存空间
  2576. IntPtr structPtr = Marshal.AllocHGlobal(size);
  2577. object obj = null;
  2578. try
  2579. {
  2580. //将byte数组拷贝到分配好的内存空间
  2581. Marshal.Copy(bytes, 0, structPtr, size);
  2582. //将内存空间转换为目标结构体
  2583. obj = Marshal.PtrToStructure(structPtr, type);
  2584. }
  2585. finally
  2586. {
  2587. //释放内存空间
  2588. Marshal.FreeHGlobal(structPtr);
  2589. }
  2590. return obj;
  2591. }
  2592. public static T ConvertBytesToStruct<T>(byte[] bytes)
  2593. {
  2594. // 将字节数组转换为结构体
  2595. GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
  2596. T myStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
  2597. handle.Free();
  2598. return myStruct;
  2599. }
  2600. #endregion 对象与字节数组转化
  2601. /// <summary>
  2602. /// 一次读取单个标签
  2603. /// </summary>
  2604. /// <typeparam name="T">需要读取的标签结构</typeparam>
  2605. /// <param name="strTagName">需要读取的标签名</param>
  2606. /// <param name="nCount">读取标签的个数</param>
  2607. /// <param name="outObj">返回相应标签值对象</param>
  2608. /// <returns></returns>
  2609. public (int, string) Read_SingleTag<T>(string strTagName, int nCount, out T outObj, Control uiControl)
  2610. {
  2611. // 初始化输出参数
  2612. outObj = default(T);
  2613. byte[] pBuf = null;
  2614. int nRet = 0;
  2615. string strRet = "";
  2616. try
  2617. {
  2618. // 创建一个标志变量,用于判断是否需要显示提示框
  2619. bool isProcessingDialogShown = false;
  2620. // 启动一个后台任务执行核心逻辑
  2621. Task<(int, string)> readTask = Task.Run(() =>
  2622. {
  2623. return Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2624. });
  2625. // 启动一个计时器任务,用于检测是否超过 5 秒
  2626. Task delayTask = Task.Delay(5000);
  2627. // 等待两个任务中的任意一个完成
  2628. Task completedTask = Task.WhenAny(readTask, delayTask).Result;
  2629. if (completedTask == delayTask)
  2630. {
  2631. // 如果超时,则显示提示框
  2632. ShowProcessingDialog(uiControl);
  2633. isProcessingDialogShown = true;
  2634. // 继续等待读取任务完成
  2635. readTask.Wait();
  2636. }
  2637. // 获取读取结果
  2638. (nRet, strRet) = readTask.Result;
  2639. // 检查类型并处理数据
  2640. string str = typeof(T).Name;
  2641. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  2642. bool containsAny = substrings.Any(substring => str.Contains(substring));
  2643. if (containsAny)
  2644. {
  2645. if (str != strRet) return (120, "变量类型不一致");
  2646. }
  2647. if (str == "String")
  2648. {
  2649. outObj = (T)(object)System.Text.Encoding.UTF8.GetString(pBuf);
  2650. }
  2651. else
  2652. {
  2653. outObj = (T)ByteToStruct(pBuf, typeof(T));
  2654. }
  2655. // 如果显示了提示框,则关闭它
  2656. if (isProcessingDialogShown)
  2657. {
  2658. CloseProcessingDialog(uiControl);
  2659. }
  2660. }
  2661. catch (Exception ex)
  2662. {
  2663. // 异常处理
  2664. return (110, ex.ToString());
  2665. }
  2666. return (nRet, "OK");
  2667. }
  2668. private Form _processingForm;
  2669. private void ShowProcessingDialog(Control uiControl)
  2670. {
  2671. if (uiControl == null)
  2672. {
  2673. throw new ArgumentNullException(nameof(uiControl), "UI 控件不能为空。");
  2674. }
  2675. // 确保在主线程上更新 UI
  2676. if (uiControl.InvokeRequired)
  2677. {
  2678. uiControl.Invoke(new Action(() => ShowProcessingDialog(uiControl)));
  2679. return;
  2680. }
  2681. // 创建并显示提示框
  2682. Form processingForm = new Form
  2683. {
  2684. Text = "请稍候",
  2685. Size = new Size(300, 100),
  2686. StartPosition = FormStartPosition.CenterScreen,
  2687. FormBorderStyle = FormBorderStyle.FixedDialog,
  2688. ControlBox = false,
  2689. TopMost = true
  2690. };
  2691. Label label = new Label
  2692. {
  2693. Text = "正在读取中,请稍后...",
  2694. Dock = DockStyle.Fill,
  2695. TextAlign = ContentAlignment.MiddleCenter
  2696. };
  2697. processingForm.Controls.Add(label);
  2698. processingForm.Show();
  2699. // 保存提示框引用以便后续关闭
  2700. _processingForm = processingForm;
  2701. }
  2702. private void CloseProcessingDialog(Control uiControl)
  2703. {
  2704. if (uiControl == null)
  2705. {
  2706. return;
  2707. }
  2708. // 确保在主线程上更新 UI
  2709. if (uiControl.InvokeRequired)
  2710. {
  2711. uiControl.Invoke(new Action(() => CloseProcessingDialog(uiControl)));
  2712. return;
  2713. }
  2714. // 关闭提示框
  2715. _processingForm?.Close();
  2716. _processingForm = null;
  2717. }
  2718. /*
  2719. public (int, string) Read_SingleTag<T>(string strTagName, int nCount, out T outObj)
  2720. {
  2721. outObj = default(T);
  2722. byte[] pBuf = null;
  2723. int nRet = 0;
  2724. string strRet = "";
  2725. try
  2726. {
  2727. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2728. if (nRet != 0) return (nRet, strRet);
  2729. string str = typeof(T).Name;
  2730. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  2731. bool containsAny = substrings.Any(substring => str.Contains(substring));
  2732. if (containsAny)
  2733. {
  2734. if (str != strRet) return (120, "变量类型不一致");
  2735. }
  2736. if (str == "String")
  2737. {
  2738. outObj = (T)(object)System.Text.Encoding.UTF8.GetString(pBuf);
  2739. return (0, "OK");
  2740. }
  2741. outObj = (T)ByteToStruct(pBuf, typeof(T));
  2742. }
  2743. catch (Exception ex)
  2744. {
  2745. return (110, ex.ToString());
  2746. }
  2747. return (0, "OK");
  2748. }*/
  2749. public (int, string) Write_SingleTag<T>(string strTagName, int nCount, T inObj)
  2750. {
  2751. byte[] pBuf = null;
  2752. int nRet = 0;
  2753. string strRet = "";
  2754. int size = 0;
  2755. try
  2756. {
  2757. string str = typeof(T).Name;
  2758. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  2759. bool containsAny = substrings.Any(substring => str.Contains(substring));
  2760. if (containsAny)
  2761. {
  2762. Type type = inObj.GetType();
  2763. if (str != type.Name) return (120, "变量类型不一致");
  2764. }
  2765. if (str == "String")
  2766. {
  2767. //size = inObj.ToString().Length + 1;
  2768. string wtStr= inObj as string;
  2769. pBuf = System.Text.Encoding.Default.GetBytes(wtStr);
  2770. size = pBuf.Length;
  2771. }
  2772. else
  2773. {
  2774. if (typeof(T).Name == "Boolean")
  2775. {
  2776. //pBuf = new byte[1];
  2777. //Type targetType = typeof(T);
  2778. //if ((bool)Convert.ChangeType(inObj, targetType))
  2779. //{
  2780. // pBuf[0] = 1;
  2781. //}
  2782. //else
  2783. //{
  2784. // pBuf[0] = 0;
  2785. //}
  2786. size = 1;
  2787. }
  2788. else
  2789. {
  2790. size = Marshal.SizeOf(typeof(T));
  2791. }
  2792. pBuf = StructToBytes(inObj, size);
  2793. }
  2794. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2795. return (nRet, strRet);
  2796. }
  2797. catch (Exception ex)
  2798. {
  2799. return (110, ex.ToString());
  2800. }
  2801. }
  2802. /// <summary>
  2803. /// 一次读取多个标签
  2804. /// </summary>
  2805. /// <param name="stTagList">需要读取的标签列表信息</param>
  2806. /// <param name="outObj">返回的相应标签对象</param>
  2807. /// <returns>执行是否成功,非0不成功,以及显示相应的失败信息</returns>
  2808. public (int, string) Read_MultiTags(List<StructTag> stTagList, out List<Object> outObj)
  2809. {
  2810. outObj = new List<Object>();
  2811. byte[][] pBuf = null;
  2812. int nRet = 0;
  2813. string strRet = "";
  2814. int nLen = stTagList.Count;
  2815. List<StructTag> TagList=new List<StructTag>();
  2816. try
  2817. {
  2818. foreach(StructTag tag in stTagList)
  2819. {
  2820. TagList.Add(new StructTag {strTagName= strTagPrefix + tag.strTagName,tTagType=tag.tTagType,nCount=tag.nCount});
  2821. }
  2822. (nRet, strRet) = Read_Tags(TagList, out pBuf);
  2823. if (nRet != 0) return (nRet, strRet);
  2824. for (int i = 0; i < nLen; i++)
  2825. {
  2826. //需要调用的方法
  2827. //MethodInfo mi = typeof(Inovance_EIP).GetMethod("ByteToStruct");
  2828. //该方法的泛型类型Type->typeof(int)
  2829. //MethodInfo miConstructed = mi.MakeGenericMethod(strTagList[i].TagType);
  2830. //var arg = { pBuf[i]};
  2831. //执行调用
  2832. //miConstructed.Invoke(null, args);
  2833. //outObj.Add(Convert.ChangeType(ByteToStruct2(pBuf[i], targetType), targetType));
  2834. Type targetType = TagList[i].tTagType;
  2835. if (targetType != null)
  2836. {
  2837. object obj = ByteToStruct(pBuf[i], targetType);
  2838. //if (obj != null)
  2839. outObj.Add(obj);
  2840. }
  2841. }
  2842. }
  2843. catch (Exception ex)
  2844. {
  2845. return (110, ex.ToString());
  2846. }
  2847. return (0, "OK");
  2848. }
  2849. /// <summary>
  2850. /// 一次写多个标签
  2851. /// </summary>
  2852. /// <param name="stTagList">需要写入的标签列表信息</param>
  2853. /// <param name="ObjList">写入的相应标签对象</param>
  2854. /// <returns>执行是否成功,非0不成功,以及显示相应的失败信息</returns>
  2855. public (int, string) Write_MultiTags(List<StructTag> stTagList, List<Object> ObjList)
  2856. {
  2857. int nRet = 0;
  2858. string strRet = "";
  2859. int nLen = stTagList.Count;
  2860. if (ObjList.Count != nLen) return (10, "标签列表和对象列表长度不一致");
  2861. List<StructTag> TagList = new List<StructTag>();
  2862. try
  2863. {
  2864. foreach (StructTag tag in stTagList)
  2865. {
  2866. TagList.Add(new StructTag { strTagName = strTagPrefix + tag.strTagName, tTagType = tag.tTagType, nCount = tag.nCount });
  2867. }
  2868. (nRet, strRet) = Write_Tags(TagList, ObjList);
  2869. return (nRet, strRet);
  2870. }
  2871. catch (Exception ex)
  2872. {
  2873. return (110, ex.ToString());
  2874. }
  2875. }
  2876. #region 清除标签缓存
  2877. /// <summary>
  2878. /// 清除标签缓存
  2879. /// </summary>
  2880. public void Clear_TagCache()
  2881. {
  2882. ResetTagInfo();
  2883. }
  2884. #endregion 清除标签缓存
  2885. }
  2886. }