Inovance_EIP.cs 122 KB

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