工控开发方面的问题:OPC服务器错误(200)

  • 主题发起人 主题发起人 小鱼钱钱
  • 开始时间 开始时间

小鱼钱钱

Unregistered / Unconfirmed
GUEST, unregistred user!
在注册opcdaauto.dll后,在d7 中导入类型库,在使用opcserver控件的时候(代码)遇到“内存分配访问无效”的问题,郁闷哪,哪位大虾帮忙解决一下?? opcserver1.connect1('OPC.SimaticNET'); OPC.SimaticNET 是我的OPC服务器的名称(在西门子软件opc scount中可以看到的名称)
 
啊!!!!!
 
前一段时间 做过 这个。。。用opc连接 ifix服务器。。。。没什么问题。。。主要 估计是不熟悉 怎么用,刚开始我也 摸索了好久才 可以的。。。你给我发个邮件 明天 给你点 代码 你参考 以下。。。
 
开发OPC客户端程序时,首先应该生成OPC服务器支持的OPC对象,然后就可以使用OPC对象支持的属性和方法,对其进行各种操作。这样使得客户程序可以像使用自己支持的数据和功能一样,去使用服务器对象支持的数据和功能。在VisualBasic6.0里,是以对象为单位对OPC服务器进行访问的。通过 OPC自动化服务器的对象模型,可以得知OPC自动化接口由以下四种对象所定义。1  OPCServer服务器对象OPCServer的一个实例,OPC服务器自动含有一个OPC组集合对象,并可在其基础上生成一个OPC浏览器对象。 OPCServer服务器对象在使用其它OPC对象前必须生成,也就是说在引用其他对象之前必须先创建OPCServer。OPCServer对象提供了对数据源访问和通信的方法,其提供了“Connect”方法来连接OPC自动化服务器。主要的属性有:StartTime(只读属性,服务器启动运行的时间)、CurrentTime(只读属性,返回服务器显示的当前时间)、LastUpdateTime(对于本OPC应用程序的最后数据更新时间)、MajorVersion(只读属性,OPC服务器的主版本号)、MinorVersion(只读属性,OPC服务器的次版本号)、Bandwith(只读属性,返回OPC服务器的不敏感区的百分比)、ServerState(只读属性,返回服务器的运行状态,这个属性是比较重要的,方便客户端程序查询服务器的状态,从而达到排除故障的目的)、ServerName(只读属性,返回客户程序所要连接的服务器名,也就是OPC服务器的ProgID)、ServerNode(服务器所在计算机名或者计算机的IP,用于连接远程的计算机)等。主要方法有:GetOPCservers(获得己经注册的OPC服务器的程序标识符,即ProgID)、Connect(用来建立与OPC数据存取服务器的连接)、Disconnect(断开与服务器的连接)、CreatBrowser(创建OPC浏览器的对象)等。事件:只有一个ServerShutDown(关闭服务器,这个事件在服务器即将关闭之前发生,OPC服务器以此通知OPC客户程序预告即将关闭,OPC客户程序应该在接到此事件通知后,立即清除所有的OPC组并断开与OPC服务器的连接)。 2 OPCGroups组集合对象OPC组的容器,包含所有客户端创建的OPCGroup对象的自动化集合。这个对象的用途是添加、清除和管理OPC组主要的属性有:DefaultGroupIsActive(新添加的OPC组的活动状态的默认值。默认初始值是活动状态)、DefaultGroupUpdateRate(新添加的OPC组的默认数据更新周期,默认初始值是1000毫秒)、DefaultGrouPDeadband(新添加的OPC组的默认不敏感区的默认值,即能引起数据变化的最小数值百分比,默认值是0%)、DefaultGroupLocaleID(新添加的OPC组区域标识符的默认值)、DefaultGroupTimeBias(新添加的OPC组的时间偏差的默认值)等。主要方法:Item(OPC组集合的默认方法。返回由集合索引指定的OPC组对象)、Add(在OPC组集合对象中添加一个组对象)、GetOPCGroup(返回指定的OPC组)、RemoveAll(为服务器关机作准备,删除所有组和标签)、Remove(删除一个指定的组)、ConnectPublicGroup(连接到公共组)等。事件:AllGroupsDataChange(由多个OPC组的数据变化而引发的事件)。3 OPCGroup组对象,OPCGroup的一个实例,它包含自身的信息,同时向OPCItems对象提供数据获取服务,它自动含有一个Items集合对象,允许客户端来组织它们需要访问的数据。OPCGroup可以作为一个单元来进行激活或停止激活操作。主要属性:Name(OPC组的名称)、IsPublic(判断是否公共组)、IsActive(控制组的激活状态。只有活动状态的OPC组才进行定期的数据更新)、IsSubscribed(控制组的订阅状态)、ClientHandle(客户句柄是由客户端程序指定的用于识别某个OPC组的长整型数。当进行数据访问或询问OPC组状态时,服务器将这个数值和结果一起返回给OPC客户程序)、 TimeBias(数据采样时间的时间偏差值,用于调整设备时间和OPC服务器时间的偏差)、DeadBand(不敏感区,只有数据变化超过此不敏感区时,服务器才触发数据变化事件发生)、UpdateRate(数据更新周期)、OPCItems(OPC组的默认属性,OPC标签集合对象)。主要方法:SyncRead(同步读OPC组内单个或多个OPC项的数据值、质量标志和采样时间)、Syncwrite(同步写入OPC组内单个或多个OPC项的数据值)、AsyncRead(异步读)、Asyncwrite(异步写)、AsyncRefresh(触发数据变化事件发生,刷新OPC组内所有活动的OPC标签的数据。结果有数据变化事件DataChange返回)等。主要事件:DataChange(在OPC组内任何OPC项的数据值或质量标志变化时触发的事件)、AsyncReadComplete(异步读结束时发生的事件)、AsyncWriteComplete(异步写结束时发生的事件)等。 4 OPCItems项集合对象,是OPC项对象的容器,自动化客户程序创建的OPCGroup对象所包含的所有OPCItems对象的自动化集合。属性:Parent(返回所属的OPC组对象)、DefaultRequestedDataType(添加OPC项时,默认的要求的数据类型。初始值是控制设备的固有数据类型,既是VT_Empty)、DefaultAccessPath(添加OPC项时,默认的数据访问路径。初始值是空)、DefaultIsActive(添加OPC项时,默认的激活状态,初始值是真)、Count(集合对象的固有属性。OPC项集合中的OPC项数)。方法:Item(返回OPC标签集合中由集合索引指定的OPC标签)、GetOPCItem(返回OPC项集合中由服务器句柄指定的OPC项)、Addltem(在OPC项集合中添加新的OPC项)、Remove(删除指定的项)、Aalidate(检查项创建的有效性)、SetActive(分别设置项为活动或非活动状态)、SetClientHandles(设置OPC项的客户句柄)、SetDataTypes(设置OPC项要求的数据类型)。 5 OPCItem项对象表示与OPC服务器内某个数据的连接。各个项包含了数据值、质量标志以及采样时间。数据值的类型为VARIANT。主要属性:ClientHandle(客户句柄是由客户端程序指定的用于识别某个OPC组的长整型数。当OPC组事件发生时,服务器将这个客户句柄和结果一起返回给OPC客户程序)、ServerHandle(服务器句柄是有OPC服务器设置的用于识别某个OPC标签的一个全局唯一长整型数)、AccessPath(返回OPC客户程序指定的访问路径)、AccessRights(返回OPC项的访问权)、ItemID(返回识别这个OPC项的标识符)、IsActive(用以控制OPC项的活动状态)、RequestedDataType(获取项的值的数据类型)、Value(返回从OPC服务器读取的最新数据值)、Quality(返回从OPC服务器读取的最新数据值的质量标志)、TimeStamp(时间戳)等。主要方法:Read(从服务器读取OPC项的数值)、Write(向服务器写入OPC项的数值)。 6 OPC浏览器对象OPCBrowser是OPC服务器名称空间的枝和叶的集合,可以浏览服务器配置中项的名字,一个OPCServer对象实例中只能有一个 OPCBrowser对象的实例。浏览器功能是选用功能,OPC服务器不支持浏览器的时候,即使执行CreateBrowser也不生成这个对象。主要属性:Organization(OPC服务器的名称空间的类型,有平面型和树型两种类型)、Filter(使用ShowBrancher或ShowLeafs方法时的浏览对象过滤器,使用这个过滤器可以缩小被浏览的名称范围)、DataType(使用ShowLeafs方法时,希望浏览的标签的数据类型)、Count(浏览结果中的浏览标签数)。 主要方法:Item(返回浏览结果中按集合索引ItemSpecifier指定的对象)、ShowBranches(将现在位置下的所有符合过滤条件的枝加入到浏览结果中)、ShowLeafs(将现在位置下的所有符合过滤条件的叶加入到浏览结果中)、MoveUp(向现在位置的上一层移动)、MoveToRoot(向名称空间的最上层移动)、MoveDown(向现在位置的下一层移动)、MoveTo(向浏览器的绝对位置移动)、GetItemID(由浏览标签的名称返回OPC标签的标识符)。 (1)建立新工程或项目,在“工程”菜单下选择“引用”,如图5-3所示。只有引用OPCDAAuoto.DLL后,在程序中才能创建服务器对象,然后进行一系列的操作。(2)在弹出的引用窗口里单击“浏览(B)…”按钮,弹出添加引用窗口,选择OPCDAAuoto.DLL文件。(3)在引用窗口里的OPCAutomation2.0前面打钩,按“确定”按钮。(4)定义全局变量,这样可以在窗体的任何方法的代码内应用。变量类型应该指定为对象型。这些对象最好在窗体的通用部分声明加上“OptionExplicit”语句,表示模块里的所有变量都需要显式声明。由于OPC自动化接口的数组的索引要求必须从1开始,而系统默认是从0开始,为了避免错误最好在代码的最初加上 “OptionBase1”语句。为了使对象可以处理事件,必须将objTestGrp和objServer的声明中加上“WithEvents”语句,表示声明的对象可以响应事件。OptionExplicitOptionBase1Dim WithEventsobjServer As OPCServerDim objGroups As OPCGroupsDim WithEventsobjTestGrp As OPCGroupDim objItems As OPCItems(5)连接OPC服务器和建立OPC组考虑到代码的可反复使用性,采用子程序进行编程。 SubConnect(strProgIDAsString,OptionalstrNodeAsString) If objServerIsNothing Then '建立一个OPC服务器对象 SetobjServer=NewOPCServer EndIf服务器状态 ServerState属性一共有OPCRunning、OPCFailed、OPCNoconfig、OPCSuspended、OPCTest和 OPCDisconnected六个值,分别表示正在运行、失败、没有配置、暂停、测试和没有连接六种OPC服务器当前的状态。如果OPC服务器没有连接,我们才执行objServer.ConnectstrProgID,strNode语句。strProgID就是ProgID,strNode就是用于远程通信的IP地址。 If objServer.ServerState = OPCDisconnected Then'连接OPC服务器 objServer.Connect strProgID,strNode EndIf 在VisualBasic中,通过执行一个Set操作实现调用其它接口的方法。 If objGroupsIsNothing Then '建立一个OPC组集合 Set objGroups = objServer.OPCGroups EndIf If objTestGrpIsNothing Then '添加一个OPC组 Set objTestGrp = objGroups.Add("Group") EndIf EndSub (6)添加OPC标签对服务器进行访问前,必须先在OPC组里添加要访问的OPC标签。 OPC客户端程序要按照用户指定的标签或者从组态文件里读取需要添加的OPC标签。Sub AddItem()Dim strItemIDs(17) As StringDim lClientHandles(17) As LongDim lErrors () As LongDimI As Integer If ObjTestGrpIsNothing Then ExitSub EndIf If NotobjItemsIsNothing Then If objItems.Count>0 Then ExitSub EndIf EndIf'设置组活动状态。只有处于活动状态的OPC才进行定期的数据更新。非活动状态的OPC组,除了在接到显然的数据读写要求外,并不收集任何数据。 If mnuSubscribtion.Checked = True Then objTestGrp.IsActive = True Else objTestGrp.IsActive=False EndIf'启动组异步通知。进行订阅的OPC组可以自动收到从服务器送来的数据变化通知。 objTestGrp.IsSubscribed=True' 建立OPC项集合SetobjItems=objTestGrp.OPCItems'生成从TAG1到TAG17的项标识符 ForI=1To17strItemIDs(I)="Server.Group.TAG"&IlClientHandles(I)=INext' 添加OPC项 CallobjItems.AddItems(17,strItemIDs,lClientHandles,lServerHandles,lErrors)EndSub(7)异步读取代码的实现在定时器事件内进行执行AsyncRead子程序的读取代码,而在读取完成事件处理返回的数据访问结果。 SubAsyncRead()DimlErrors()AsLongIfobjTestGrpIsNothingThenExitSubEndIfIfobjTestGrp.OPCItems.Count>0Then' 异步读取 lTransID_Rd=lTransID_Rd+1objTestGrp.AsyncRead17,lServerHandles,lErrors,lTransID_Rd,lCancelID_RdEndIfEndSubPrivateSubobjTestGrp_AsyncReadComplete(_ByValTransactionIDAsLong,ByValNumItemsAsLong,_ClientHandles()AsLong,ItemValues()AsVariant,_Qualities()AsLong,TimeStamps()AsDate,Errors()AsLong)……Sub(8)在按钮中执行AsyncWrite子程序,完成异步写的操作。 SubAsyncWrite(nIndexAsInteger,ByRefvtItemValues()AsVariant,_ByReflErrors()AsLong)DimlHandle(1)AsLongIfobjTestGrpIsNothingThenExitSubEndIfIfobjTestGrp.OPCItems.Count>0ThenlHandle(1)=lServerHandles(nIndex)' 异步写入 lTransID_Wt=lTransID_Wt+1objTestGrp.AsyncWrite1,lHandle(),vtItemValues,_lErrors,lTransID_Wt,lCancelID_WtEndIfEndSub(9)断开OPC服务器连接着OPC服务器的OPC客户应用程序,在退出前必须断开和OPC服务器的连接。因为OPC服务器并不知道OPC客户应用程序的退出。如果不先断开连接,那么OPC服务器使用的计算机资源就不会被释放。如果这样的问题反复发生,久而久之,连续运转的自动控制系统可能会计算机资源渐渐枯竭从而发生严重问题,可以显式地把它设置为“Nothing”。 SubDisconnect()DimlErrors()AsLongIfNotobjItemsIsNothingThenIfobjItems.Count>0ThenobjItems.Remove17,lServerHandles,lErrors' 清除OPC项 EndIfSetobjItems=NothingEndIfIfNotobjTestGrpIsNothingThenobjGroups.Remove"Group"' 清除OPC组 SetobjTestGrp=NothingEndIfIfNotobjGroupsIsNothingThenSetobjGroups=NothingEndIfIfNotobjServerIsNothingThenIfobjServer.ServerState& lt;>OPCDisconnectedThenobjServer.Disconnect'断开OPC服务器.EndIfSetobjServer=NothingEndIfEndSubWTOPCSvr.DLL作为一个快速开发OPC服务器的工具包,它封装了所有关于COM和OPC的技术细节,将Microsoft公司的OLE、COM、DCOM技术和OPC的技术细节隐藏起来,使开发OPC服务器的工作集中在特定的数据采集任务上来。利用DLL开发OPC服务器的开发者无需考虑许多涉及到底层接口实现方面的工作,开发者无须掌握ATL、 COM/DCOM,也无须了解OPC技术的细节,只需具有基本的编程基础即可快速上手。开发者的应用程序完全可以在一个较高层次上去描述OPC数据。利用这个DLL也可以很容易的实现对现有系统的改造,因为它可以很容易地集成到现有的应用系统中,而无需太多的工作。该工具包支持多个客户端并发访问服务器,并为每个客户端创建一个独立线程。WTOPCSvr.DLL工具包其实就是一个动态链接库(DLL)。支持OPCl.0和OPC2.0数据存取规范定义的所有接口,包括实现了浏览器功能的接口。服务器应用程序通过传递一个名字和值给动态链接库去创建过程标签,动态链接库记录这个数据点,同时传送给所有使用这个数据点的客户。任何时候这个服务器应用程序都可以改变这个数据点的值,而所有使用这个数据点的客户都会得到数据值改变的通报。一个连接到服务器的客户改变任何过程标签都会得到调用返回通报消息。动态链接库还支持动态创建OPC标签,如果一个客户请求一个还没有创建的标签,则产生一个调用返回,应用程序就根据这个调用返回的信息创建一个标签。使用这个动态链接库(WTOPCSvr.DLL)可以迅速地开发OPC数据存取服务器,它提供了一些把定制数据集成到OPC服务器的易于使用的API函数。另外这个动态链接库可以很容易的集成到现有应用中,也可以集成到一个新的应用中。使用动态链接库开发OPC服务器时,关键要求用户对动态链接库的各个API函数要熟悉,从而提高软件开发的灵活性。这个动态链接库包含五大功能块:调用返回定义、初始化和注册函数、 OPC项函数、实时信息函数和辅助功能函数。1 调用返回定义明确地定义了DLL用于返回给服务器程序的调用返回的具体含义,以实现客户应用与服务器应用之间的数据交换,DLL提供了以下一些API函数。 DeclareFunctionEnableUnknownItemNotificationLib"WtOPCSvr"Alias"_EnableUnknownItemNotification@4" (ByValCallbackAsLong)AsLong:这个函数的返回值表示一个客户请求了一个没有定义或是己经被暂停刷新的标签,但无论客户请求的标签是否是己定义的标签,这个函数都定义了一个从DLL返回的调用返回。当连接建立后,服务器应用可以使用这个调用返回对动态创建的标签进行操作。 DeclareFunctionEnableItemRemovalNotificationLib"WtOPCSvr"Alias"_EnableItemRemovalNotification@4" (ByValCallbackAsLong)AsLong:当对一个标签的最后客户引用释放后,这个函数将定义一个来自DLL的调用返回,服务器应用程序可以删除这个标签或暂停这个标签的刷新。 DeclareFunctionEnableDisconnectNotificationLib"WtOPCSvr"Alias"_EnableDisconnectNotification@4" (ByValCallbackAsLong)AsLong:当客户应用请求断开连接时,这个函数产生一个来自DLL的调用返回通知服务器应用断开连接。 DeclareFunctionEnableWriteNotificationLib"WtOPCSvr"Alias"_EnableWriteNotification@8" (ByValCallbackAsLong,ByValConvertToNativeAsLong)AsLong:当OPC客户写一个己定义的标签时,这个函数产生一个来自DLL的调用返回。正常情况下,DLL将把值转变成项的私有类型,但在某些情况下,它要求应用自己完成这个转变过程。2 初始化与注册函数DeclareFunctionInitWTOPCsvrLib"WtOPCSvr"Alias"_InitWTOPCsvr@8" (ByRefCLSID_SvrAsByte,ByValServerRateAsLong)AsLong:这个函数实现对DCOM的初始化和创建OPC 服务器对象。其中参数CLSID_Svr是OPC服务器的类标识(CLSID)——用于OPC客户连接服务器;参数ServerRate定义了客户的数据刷新速率,其单位是毫秒。如果函数调用成功则返回TRUE,否则返回FALSE。 DeclareFunctionUpdateRegistryLib"WtOPCSvr"Alias"_UpdateRegistry@16" (ByRefCLSID_SvrAsByte,ByRefNameAsByte,ByRefDescrAsByte,ByRefExePathAsByte)AsLong:这个函数封装了Windows注册函数,用于OPC服务器的注册。其中参数CLSID_Svr是OPC服务器的类标识(CLSID);参数Name定义了服务器的名字;参数Descr可以是任何描述服务器的字符串,但常常包含一些版本信息;参数ExePath定义了可执行程序的完整的Windows路径。如果函数调用成功则返回TRUE,否则返回FALSE。 DeclareFunctionUnregisterServerLib"WtOPCSvr"Alias"_UnregisterServer@8" (ByRefCLSID_SvrAsByte,ByRefNameAsByte)AsLong:这是一个服务器注销函数,其参数CLSID_Svr是 OPC服务器的类标识(CLSID);参数Name为服务器的名字。如果函数调用成功则返回TRUE,否则返回FALSE。3 OPC项函数 DeclareFunctionCreateTagLib"WtOPCSvr"Alias"_CreateTag@28" (ByRefNameAsByte,ByValValueAsVariant,ByValInitialQualityAsInteger,ByValIsWritableAsLong)AsLong:这是一个在动态链接库里创建过程标签的函数,参数Name定义了OPC客户要访问的过程标签,这个名字字符串可以是服务器可接受的任何文本字符串,其中也可使用分层名字(使用“.”分隔符),这将导致动态链接库创建OPC分层名字空间;参数Value定义了标签的初始数据;参数 InitialQuality定义了标签的OPC属性标志;参数IsWriteable决定标签是否是可写标签。如果标签创建成功,函数返回数据点的句柄 (HANDLE),否则返回INVALID_HANDLE_VALUE。 DeclareFunctionUpdateTagLib"WtOPCSvr"Alias"_UpdateTag@24" (ByValTagHandleAsLong,ByValValueAsVariant,ByValQualityAsInteger)AsLong:这个函数调用实现对过程标签的数据刷新。Value就是来自现场硬件的数据。 DeclareFunctionUpdateTagWithTimeStampLib"WtOPCSvr"Alias"_UpdateTagWithTimeStamp@32" (ByValTagHandleAsLong,ByValValueAsVariant,ByValQualityAsInteger,ByValTimestampAsDouble)AsLong:这个函数允许应用改变一个己定义的标签的值、属性标志和时间标签。如果应用没有提供时间标签(timestamp),则DLL将采用系统时间。参数 TagHandle表示数据点;参数Value表示数据值;参数Quality表示新的属性条件。如果函数调用成功则返回TRUE,否则返回FALSE。 DeclareFunctionSetTagPropertiesLib"WtOPCSvr"Alias"_SetTagProperties@28" (ByValTagHandleAsLong,ByValPropertyIDAsLong,ByRefDescriptionAsByte,ByValValueAsVariant)AsLong:任何数量的OPC项属性都可以用这个函数设置,DLL保持了所有已定义属性的一个列表,OPC客户可以访问这些属性。 DeclareFunctionUpdateTagByNameLib"WtOPCSvr"Alias"_UpdateTagByName@24" (ByRefNameAsByte,ByValValueAsVariant,ByValQualityAsInteger)AsLong:可以使用这个函数来改变一个已定义过程标签的值。 DeclareFunctionSuspendTagUpdatesLib"WtOPCSvr"Alias"_SuspendTagUpdates@8" (ByValTagHandleAsLong,ByValOnOffAsLong)AsLong:这个函数可以使服务器知道一个客户描述的特殊标签的调用返回。在多数情况下,服务器是随着其接收数据的变化而刷新标签的,DLL处理所有客户请求、通报和刷新。在一定条件下,当客户访问一个项时,希望服务器仅仅刷新OPC标签数据库。通过暂停刷新功能,当客户试图访问这个项时,DLL将处理一个未知项的调用返回,然后,服务器开始重新开始刷新标签直到下一个暂停刷新产生。TagHandle定义了暂停刷新的项。 DeclareFunctionReadTagLib"WtOPCSvr"Alias"_ReadTag@8" (ByValTagHandleAsLong,ByRefValueAsVariant)AsLong:这是一个读标签的函数。 DeclareFunctionReadTagWithTimeStampLib"WtOPCSvr"Alias"_ReadTagWithTimeStamp&16" (ByValTagHandleAsLong,ByRefValueAsVariant,ByRefQualityAsInteger,ByRefTimestampAsFileTime)AsLong:应用程序使用这个函数去获取一个标签的当前值。参数Value表示了接收的数据值,参数Timestamp是标签的当前时间标签值。4 实时信息 DeclareFunctionStartUpdateTagsLib"WtOPCSvr"Alias"_StartUpdateTags@0" ()AsLong:开始刷新。 DeclareFunctionUpdateTagToListLib"WtOPCSvr"Alias"_UpdateTagToList@24" (ByValTagHandleAsLong,ByValValueAsVariant,ByValQualityAsInteger)AsLong:刷新标签列表。DeclareFunctionEndUpdateTagsLib"WtOPCSvr"Alias"_EndUpdateTags@0" ()AsLong:上面三个函数必须一起使用,它们一起提供了一次刷新多个标签的有效方式。首先调用StartUpdateTags,然后用 UpdateTagToList代替UpdateTag()调用,当所有标签都被刷新后再调用EndUpdateTags()结束此次刷新操作。5 辅助功能函数 DeclareFunctionRefreshAllClientsLib"WtOPCSvr"Alias"_RefreshAllClients@0" ()AsLong:服务器可以使用此函数对所有连接的客户进行初始化。正常情况下,客户应用数据是基于DLL中的异步时针刷新的,这个函数让服务器可以刷新所有客户数据。 DeclareFunctionResetServerRateLib"WtOPCSvr"Alias"_ResetServerRate@4" (ByValServerRateAsLong)AsLong:此函数用于改变服务器应用的数据刷新率。 DeclareFunctionSetVendorInfoLib"WtOPCSvr"Alias"_SetVendorInfo@4" (ByRefVendorInfoAsByte)AsLong:设置一些服务器的版本信息。 DeclareFunctionNumbrClientConnectionsLib"WtOPCSvr"Alias"_NumbrClientConnections@0" ()AsLong:这个函数返回当前连接到服务器的客户数。 DeclareSubRequestDisconnectLib"WtOPCSvr"Alias"_RequestDisconnect@0"():此函数提供了请求所有客户断开连接的功能,但它并不保证这个请求得到响应或者客户真正断开连接。服务器请求客户断开的功能仅仅对那些符合OPC2.0和 OPC3.0规范的客户有用。DeclareFunctionRemoveTagLib"WtOPCSvr"Alias"_RemoveTag@4" (ByValTagHandleAsLong)AsLong:此函数从DLL中删除一个过程标签。如果在删除过程标签时有客户连接正在访问这个标签,则这个连接仍然有效,但是将没有新的数据来刷新这个连接。6 对报警与事件的支持 DeclareFunctionUserAEMessageLib"WtOPCSvr"Alias"_UserAEMessage@8" (ByRefMsgAsByte,ByValSeverityAsLong)AsLong:此函数发送用户定义的事件消息给所有连接的OPC报警与事件客户。 DeclareFunctionSetItemLevelAlarmLib"WtOPCSvr"Alias"_SetItemLevelAlarm@20" (ByValTagHandleAsLong,ByValLevelIDAsLong,ByValLimitAsSingle,ByValSeverityAsLong,ByValEnabledAsLong)AsLong:每个过程标签可以定义几个报警级别,DLL将检测所有报警级别同时在刷新项时通知连接的OPC报警与事件客户。参数LevelID有以下几个级别:#defineID_LOLO_LIMITl、#defineID_LO_LIMIT2、#defineID_HI_LIMIT3、#defineID_HIHI_LIMIT4。 DeclareFunctionGetItemLevelAlarmLib"WtOPCSvr"Alias"_GetItemLevelAlarm@20" (ByValTagHandleAsLong,ByValLevelIDAsLong,ByRefLimitAsSingle,ByRefSeverityAsLong,ByRefEnabledAsLong)AsLong:获取一个过程标签的报警级别。我需要在wince下开发opcserver,急求wince下的opc开发工具。lq74@21cn.com 当然支持,包括DCOM。    只是在COM对象的支持上不完全,如不支持serverlist方法查找OPC服务器。 把分给我吧
 
先谢谢令狐小侠同学, 确实是不熟悉怎么用,以前从来没接触过opc的。就执行到 opcserver1.connect1('OPC.SimaticNET') 的时候报“内存分配访问无效”的错误。把你写的发给我参考一下吧,要delphi的哦
 
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OpcEnumLib_TLB, OleServer, OPCAutomation_TLB, StdCtrls, ComCtrls, ExtCtrls;type TForm1 = class(TForm) Button1: TButton; OPCServer1: TOPCServer; tvOPCServers: TTreeView; StatusBar1: TStatusBar; Timer1: TTimer; Button2: TButton; Button3: TButton; Edit1: TEdit; ListBox1: TListBox; OPCGroup1: TOPCGroup; OPCGroups1: TOPCGroups; CheckBox1: TCheckBox; procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject); procedure ListBox1Click(Sender: TObject); procedure CheckBox1Click(Sender: TObject); procedure tvOPCServersDblClick(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);var ig:IOPCGroup; vs:OleVariant; i:integer; tnTmp:TTreeNode; begin vs := OPCServer1.GetOPCServers; for i := VarArrayLowBound(vs, 1) to VarArrayHighBound(vs, 1) do begin tnTmp := TTreeNode.Create(tvOPCServers.Items); tnTmp.Text := vs; tvOPCServers.Items.Add(tnTmp, vs); listbox1.Items.Add(vs); end; end;procedure TForm1.Timer1Timer(Sender: TObject);begin StatusBar1.Panels[0].Text:=DateTimeToStr(now);end;procedure TForm1.FormCreate(Sender: TObject);beginTimer1Timer(nil);end;procedure TForm1.Button3Click(Sender: TObject); var og:IOPCGroup;begin OPCServer1.OPCGroups.Add(edit1.Text);end;procedure TForm1.ListBox1Click(Sender: TObject); var ig:IOPCGroup; vs:OleVariant; i:integer;begin if (tvOPCServers.SelectionCount <= 0) or (not Checkbox1.Checked) then exit;end;procedure TForm1.CheckBox1Click(Sender:TObject);begin if CheckBox1.Checked and (tvOPCServers.SelectionCount > 0)then begin OPCServer1.Connect1(tvOPCServers.Selected.Text); Caption := Format('Connect to OPC Server %s...',[tvOPCServers.Selected.Text]); end else begin OPCServer1.Disconnect; Caption:=Format('Disconnect OPC Server %s...',[tvOPCServers.Selected.Text]); end;end;procedure TForm1.tvOPCServersDblClick(Sender: TObject); var br:OPCBROWSER; lf:OleVariant; i: integer; strTmp: string; curNode,tnParent:TTreeNode; function ExplandOPCServer(ABr: OPCBROWSER): boolean; var j: integer; tnP1: TTreeNode; begin try ABr.ShowBranches; if ABr.Count > 0 then for j := 1 to ABr.Count do begin tnP1:=curNode; curNode:=tvOPCServers.Items.AddChild(curNode,ABr.Item(j)); ABr.MoveDown(ABr.Item(j)); ExplandOPCServer(Abr); curNode:=tnP1; end else begin ABr.ShowLeafs(lf); for j := 1 to ABr.Count do begin tvOPCServers.Items.AddChild(curNode, ABr.Item(j)); end;// 就应该返回上一级// ABr.ShowBranches; ABr.MoveUp; ABr.ShowBranches; end; finally // end; end; begin// 展开相应的OPCSERVER。 tvOPCServers.Selected.DeleteChildren; OPCServer1.Connect1(tvOPCServers.Selected.Text); br := OPCServer1.CreateBrowser; curNode := tvOPCServers.Selected; tnParent := curNode; ExplandOPCServer(br); end;end.
 
object Form1: TForm1 Left = 191 Top = 192 Caption = 'Form1' ClientHeight = 580 ClientWidth = 809 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object Button1: TButton Left = 88 Top = 72 Width = 75 Height = 25 Caption = 'Button1' TabOrder = 0 OnClick = Button1Click end object tvOPCServers: TTreeView Left = 416 Top = 16 Width = 305 Height = 137 Indent = 19 TabOrder = 1 OnDblClick = tvOPCServersDblClick end object StatusBar1: TStatusBar Left = 0 Top = 561 Width = 809 Height = 19 Panels = < item Width = 500 end item Width = 50 end> end object Button2: TButton Left = 88 Top = 128 Width = 75 Height = 25 Caption = 'Button2' TabOrder = 3 end object Button3: TButton Left = 168 Top = 344 Width = 75 Height = 25 Caption = 'Button3' TabOrder = 4 OnClick = Button3Click end object Edit1: TEdit Left = 16 Top = 208 Width = 121 Height = 21 TabOrder = 5 Text = 'Edit1' end object ListBox1: TListBox Left = 424 Top = 200 Width = 305 Height = 281 ItemHeight = 13 TabOrder = 6 OnClick = ListBox1Click end object CheckBox1: TCheckBox Left = 184 Top = 216 Width = 97 Height = 17 Caption = 'CheckBox1' TabOrder = 7 OnClick = CheckBox1Click end object OPCServer1: TOPCServer AutoConnect = False ConnectKind = ckRunningOrNew Left = 96 Top = 24 end object Timer1: TTimer OnTimer = Timer1Timer Left = 232 Top = 24 end object OPCGroup1: TOPCGroup AutoConnect = False ConnectKind = ckRunningOrNew Left = 56 Top = 24 end object OPCGroups1: TOPCGroups AutoConnect = False ConnectKind = ckRunningOrNew Left = 16 Top = 24 endend
 
感谢dorry的代码,不过不管怎么试还是提示这个错误,问题没有解决,先不散分了。
 
问题终于解决啦,哈哈,原来是opcdaauto.dll的版本问题,晕哦谢谢令狐小侠的dorry给予的帮助
 
后退
顶部