Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1267490
  • 博文数量: 788
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 7005
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-19 15:52
文章存档

2017年(81)

2011年(1)

2009年(369)

2008年(337)

分类:

2009-03-02 11:35:52



小弟,初次使用opc,知道opc是基于com的技术,请问各位大侠使用opc还需要特殊操作吗?  
  这是我在网上下   载的例子,这段代码有什么问题?我总是运行不成功。  
  在HR   :=   GroupAddItem(GroupIf,   Item0Name,   0,   VT_EMPTY,   Item0Handle  
          ItemType);一句中,hr总是返回负值,请问为什么,另外在  
      HR   :=   GroupAdviseTime(GroupIf,   AdviseSink,   AsyncConnection);这一句总是提示   异常   接口不支持   interface   not   supportd,就是DataIf   :=   GroupIf   as   IDataObject;groupif   是   IOPCItemMgt类型的  
  源代码:  
    //   among   other   things,   this   call   makes   sure   that   COM   is   initialized  
      Application.Initialize;  
      Writeln('========================================================');  
      Writeln('Simple   OPC   client   program,   by   Mike   Dillamore,   1998-2006.');  
      Writeln('Tested   for   compatibility   with   Delphi   3-7   and   2005,   2006   ');  
      Writeln('Requires   Simulation   OPC   server   from   Matrikon,                       ');  
      Writeln('but   easily   modified   for   use   with   other   servers.                   ');  
      Writeln('========================================================');  
      Writeln;  
   
      //   this   is   for   DCOM:  
      //   without   this,   callbacks   from   the   server   may   get   blocked,   depending   on  
      //   DCOM   configuration   settings  
      HR   :=   CoInitializeSecurity(  
          nil,                                         //   points   to   security   descriptor  
          -1,                                           //   count   of   entries   in   asAuthSvc  
          nil,                                         //   array   of   names   to   register  
          nil,                                         //   reserved   for   future   use  
          RPC_C_AUTHN_LEVEL_NONE,   //   the   default   authentication   level   for   proxies  
          RPC_C_IMP_LEVEL_IMPERSONATE,//   the   default   impersonation   level   for   proxies  
          nil,                                         //   used   only   on   Windows   2000  
          EOAC_NONE,                             //   additional   client   or   server-side   capabilities  
          nil                                           //   reserved   for   future   use  
          );  
      if   Failed(HR)   then  
      begin  
          Writeln('Failed   to   initialize   DCOM   security');  
      end;  
   
      try  
          //   we   will   use   the   custom   OPC   interfaces,   and   OPCProxy.dll   will   handle  
          //   marshaling   for   us   automatically   (if   registered)  
          ServerIf   :=   CreateComObject(ProgIDToClassID(ServerProgID))   as   IOPCServer;  
      except  
          ServerIf   :=   nil;  
      end;  
      if   ServerIf   <>   nil   then  
      begin  
          Writeln('Connected   to   OPC   server');  
      end  
      else   begin  
          Writeln('Unable   to   connect   to   OPC   server');  
          Exit;  
      end;  
   
      //   now   add   a   group  
      HR   :=   ServerAddGroup(ServerIf,   'MyGroup',   True,   500,   0,   GroupIf,   GroupHandle);  
      if   Succeeded(HR)   then  
      begin  
          Writeln('Added   group   to   server');  
      end  
      else   begin  
          Writeln('Unable   to   add   group   to   server');  
          Exit;  
      end;  
   
      //   now   add   an   item   to   the   group  
      HR   :=   GroupAddItem(GroupIf,   Item0Name,   0,   VT_EMPTY,   Item0Handle,  
          ItemType);  
      if   Succeeded(HR)   then  
      begin  
          Writeln('Added   item   0   to   group');  
      end  
      else   begin  
          Writeln('Unable   to   add   item   0   to   group');  
          ServerIf.RemoveGroup(GroupHandle,   False);  
          Exit;  
      end;  
      //   now   add   a   second   item   to   the   group  
      HR   :=   GroupAddItem(GroupIf,   Item1Name,   1,   VT_EMPTY,   Item1Handle,  
          ItemType);  
      if   Succeeded(HR)   then  
      begin  
          Writeln('Added   item   1   to   group');  
      end  
      else   begin  
          Writeln('Unable   to   add   item   1   to   group');  
          ServerIf.RemoveGroup(GroupHandle,   False);  
          Exit;  
      end;  
   
      //   set   up   an   IDataObject   advise   callback   for   the   group  
      AdviseSink   :=   TOPCAdviseSink.Create;  
      HR   :=   GroupAdviseTime(GroupIf,   AdviseSink,   AsyncConnection);  
      if   Failed(HR)   then  
      begin  
          Writeln('Failed   to   set   up   IDataObject   advise   callback');  
      end  
      else   begin  
          Writeln('IDataObject   advise   callback   established');  
          //   continue   waiting   for   callbacks   for   10   seconds  
          StartTime   :=   Now;  
          while   (Now   -   StartTime)   <   (10   *   OneSecond)   do  
          begin  
              Application.ProcessMessages;  
          end;  
          //   end   the   IDataObject   advise   callback  
          GroupUnadvise(GroupIf,   AsyncConnection);  
      end;  
   
      //   now   set   up   an   IConnectionPointContainer   data   callback   for   the   group  
      OPCDataCallback   :=   TOPCDataCallback.Create;  
      HR   :=   GroupAdvise2(GroupIf,   OPCDataCallback,   AsyncConnection);  
      if   Failed(HR)   then  
      begin  
          Writeln('Failed   to   set   up   IConnectionPointContainer   advise   callback');  
      end  
      else   begin  
          Writeln('IConnectionPointContainer   data   callback   established');  
          //   continue   waiting   for   callbacks   for   10   seconds  
          StartTime   :=   Now;  
          while   (Now   -   StartTime)   <   (10   *   OneSecond)   do  
          begin  
              Application.ProcessMessages;  
          end;  
          //   end   the   IConnectionPointContainer   data   callback  
          GroupUnadvise2(GroupIf,   AsyncConnection);  
      end;  
   
      //   now   try   to   read   the   item   value   synchronously  
      HR   :=   ReadOPCGroupItemValue(GroupIf,   Item0Handle,   ItemValue,   ItemQuality);  
      if   Succeeded(HR)   then  
      begin  
          if   (ItemQuality   and   OPC_QUALITY_MASK)   =   OPC_QUALITY_GOOD   then  
          begin  
              Writeln('Item   0   value   read   synchronously   as   ',   ItemValue);  
          end  
          else   begin  
              Writeln('Item   0   value   was   read   synchronously,   but   quality   was   not   good');  
          end;  
      end  
      else   begin  
          Writeln('Failed   to   read   item   0   value   synchronously');  
      end;  
   
      //   finally   write   the   value   just   read   from   item   0   into   item   1  
      HR   :=   WriteOPCGroupItemValue(GroupIf,   Item1Handle,   ItemValue);  
      if   Succeeded(HR)   then  
      begin  
          Writeln('Item   1   value   written   synchronously');  
      end  
      else   begin  
          Writeln('Failed   to   write   item   1   value   synchronously');  
      end;  
   
      //   wait   for   1   second  
      StartTime   :=   Now;  
      while   (Now   -   StartTime)   <   OneSecond   do  
      begin  
          Application.ProcessMessages;  
      end;  
   
      //   and   try   to   read   it   back  
      HR   :=   ReadOPCGroupItemValue(GroupIf,   Item1Handle,   ItemValue,   ItemQuality);  
      if   Succeeded(HR)   then  
      begin  
          if   (ItemQuality   and   OPC_QUALITY_MASK)   =   OPC_QUALITY_GOOD   then  
          begin  
              Writeln('Item   1   value   read   synchronously   as   ',   ItemValue);  
          end  
          else   begin  
              Writeln('Item   1   value   was   read   synchronously,   but   quality   was   not   good');  
          end;  
      end  
      else   begin  
          Writeln('Failed   to   read   item   0   value   synchronously');  
      end;  
   
      //   now   cleanup  
      HR   :=   ServerIf.RemoveGroup(GroupHandle,   False);  
      if   Succeeded(HR)   then  
      begin  
          Writeln('Removed   group');  
      end  
      else   begin  
          Writeln('Unable   to   remove   group');  
      end;  
   
      //   Delphi   runtime   library   will   release   all   interfaces   automatically   when  
      //   variables   go   out   of   scope  
 

 
  function   ServerAddGroup(ServerIf:   IOPCServer;   Name:   string;   Active:   BOOL;  
                      UpdateRate:   DWORD;   ClientHandle:   OPCHANDLE;   var   GroupIf:   IOPCItemMgt;  
                      var   ServerHandle:   OPCHANDLE):   HResult;  
  function   GroupAddItem(GroupIf:   IOPCItemMgt;   ItemID:   string;  
                      ClientHandle:   OPCHANDLE;   DataType:   TVarType;  
                      var   ServerHandle:   OPCHANDLE;   var   CanonicalType:   TVarType):   HResult;  
  function   GroupRemoveItem(GroupIf:   IOPCItemMgt;  
                      ServerHandle:   OPCHANDLE):   HResult;  
  function   GroupAdviseTime(GroupIf:   IUnknown;   Sink:   IAdviseSink;  
                      var   AsyncConnection:   Longint):   HResult;  
  function   GroupUnAdvise(GroupIf:   IUnknown;   AsyncConnection:   Longint):   HResult;  
  function   GroupAdvise2(GroupIf:   IUnknown;   OPCDataCallback:   IOPCDataCallback;  
                      var   AsyncConnection:   Longint):   HResult;  
  function   GroupUnadvise2(GroupIf:   IUnknown;  
                      var   AsyncConnection:   Longint):   HResult;  
  function   ReadOPCGroupItemValue(GroupIf:   IUnknown;   ItemServerHandle:   OPCHANDLE;  
                      var   ItemValue:   string;   var   ItemQuality:   Word):   HResult;  
  function   WriteOPCGroupItemValue(GroupIf:   IUnknown;   ItemServerHandle:   OPCHANDLE;  
                      ItemValue:   OleVariant):   HResult;  
   
  implementation  
   
  //   utility   functions   wrapping   OPC   methods  
   
  //   wrapper   for   IOPCServer.AddGroup  
  function   ServerAddGroup(ServerIf:   IOPCServer;   Name:   string;   Active:   BOOL;  
                      UpdateRate:   DWORD;   ClientHandle:   OPCHANDLE;   var   GroupIf:   IOPCItemMgt;  
                      var   ServerHandle:   OPCHANDLE):   HResult;  
  var  
      PercentDeadBand:   Single;  
      RevisedUpdateRate:   DWORD;  
  begin  
      Result   :=   E_FAIL;  
      if   ServerIf   <>   nil   then  
      begin  
          PercentDeadBand   :=   0.0;  
          Result   :=   ServerIf.AddGroup(PWideChar(WideString(Name)),   Active,   UpdateRate,  
                                                          ClientHandle,   nil,   @PercentDeadBand,   0,  
                                                          ServerHandle,   RevisedUpdateRate,   IOPCItemMgt,  
                                                          IUnknown(GroupIf));  
      end;  
      if   Failed(Result)   then  
      begin  
          GroupIf   :=   nil;  
      end;  
  end;  
   
  //   wrapper   for   IOPCItemMgt.AddItems   (single   item   only)  
  function   GroupAddItem(GroupIf:   IOPCItemMgt;   ItemID:   string;  
                      ClientHandle:   OPCHANDLE;   DataType:   TVarType;  
                      var   ServerHandle:   OPCHANDLE;   var   CanonicalType:   TVarType):   HResult;  
  var  
      ItemDef:   OPCITEMDEF;  
      Results:   POPCITEMRESULTARRAY;  
      Errors:   PResultList;  
  begin  
      if   GroupIf   =   nil   then  
      begin  
          Result   :=   E_FAIL;  
          Exit;  
      end;  
      with   ItemDef   do  
      begin  
          szAccessPath   :=   '';  
          szItemID   :=   PWideChar(WideString(ItemID));  
          bActive   :=   True;  
          hClient   :=   ClientHandle;  
          dwBlobSize   :=   0;  
          pBlob   :=   nil;  
          vtRequestedDataType   :=   DataType;  
      end;  
      Result   :=   GroupIf.AddItems(1,   @ItemDef,   Results,   Errors);  
      if   Succeeded(Result)   then  
      begin  
          //Result   :=   Errors[0];  
          try  
              if   Succeeded(Result)   then  
              begin  
                  ServerHandle   :=   Results[0].hServer;  
                  CanonicalType   :=   Results[0].vtCanonicalDataType;  
              end;  
          finally  
              CoTaskMemFree(Results[0].pBlob);  
              CoTaskMemFree(Results);  
              CoTaskMemFree(Errors);  
          end;  
      end;  
  end;

//   wrapper   for   IOPCItemMgt.RemoveItems   (single   item   only)  
  function   GroupRemoveItem(GroupIf:   IOPCItemMgt;  
                      ServerHandle:   OPCHANDLE):   HResult;  
  var  
      Errors:   PResultList;  
  begin  
      if   GroupIf   =   nil   then  
      begin  
          Result   :=   E_FAIL;  
          Exit;  
      end;  
      Result   :=   GroupIf.RemoveItems(1,   @ServerHandle,   Errors);  
      if   Succeeded(Result)   then  
      begin  
          Result   :=   Errors[0];  
          CoTaskMemFree(Errors);  
      end;  
  end;  
   
  //   wrapper   for   IDataObject.DAdvise   on   an   OPC   group   object  
  function   GroupAdviseTime(GroupIf:   IUnknown;   Sink:   IAdviseSink;  
                      var   AsyncConnection:   Longint):   HResult;  
  var  
      DataIf:   IDataObject;  
      Fmt:   TFormatEtc;  
  begin  
      Result   :=   E_FAIL;  
      try  
          DataIf   :=   GroupIf   as   IDataObject;  
      except  
          DataIf   :=   nil;  
      end;  
      if   DataIf   <>   nil   then  
      begin  
          with   Fmt   do  
          begin  
              cfFormat   :=   OPCSTMFORMATDATATIME;  
              dwAspect   :=   DVASPECT_CONTENT;  
              ptd   :=   nil;  
              tymed   :=   TYMED_HGLOBAL;  
              lindex   :=   -1;  
          end;  
          AsyncConnection   :=   0;  
          Result   :=   DataIf.DAdvise(Fmt,   ADVF_PRIMEFIRST,   Sink,   AsyncConnection);  
          if   Failed(Result)   then  
          begin  
              AsyncConnection   :=   0;  
          end;  
      end;  
  end;  
   
  //   wrapper   for   IDataObject.DUnadvise   on   an   OPC   group   object  
  function   GroupUnAdvise(GroupIf:   IUnknown;   AsyncConnection:   Longint):   HResult;  
  var  
      DataIf:   IDataObject;  
  begin  
      Result   :=   E_FAIL;  
      try  
          DataIf   :=   GroupIf   as   IDataObject;  
      except  
          DataIf   :=   nil;  
      end;  
      if   DataIf   <>   nil   then  
      begin  
          Result   :=   DataIf.DUnadvise(AsyncConnection);  
      end;  
  end;  
   
  //   wrapper   for   setting   up   an   IOPCDataCallback   connection  
  function   GroupAdvise2(GroupIf:   IUnknown;   OPCDataCallback:   IOPCDataCallback;  
                      var   AsyncConnection:   Longint):   HResult;  
  var  
      ConnectionPointContainer:   IConnectionPointContainer;  
      ConnectionPoint:   IConnectionPoint;  
  begin  
      Result   :=   E_FAIL;  
      try  
          ConnectionPointContainer   :=   GroupIf   as   IConnectionPointContainer;  
      except  
          ConnectionPointContainer   :=   nil;  
      end;  
      if   ConnectionPointContainer   <>   nil   then  
      begin  
          Result   :=   ConnectionPointContainer.FindConnectionPoint(IID_IOPCDataCallback,  
              ConnectionPoint);  
          if   Succeeded(Result)   and   (ConnectionPoint   <>   nil)   then  
          begin  
              Result   :=   ConnectionPoint.Advise(OPCDataCallback   as   IUnknown,  
                  AsyncConnection);  
          end;  
      end;  
  end;  
   
  //   wrapper   for   cancelling   up   an   IOPCDataCallback   connection  
  function   GroupUnadvise2(GroupIf:   IUnknown;  
                      var   AsyncConnection:   Longint):   HResult;  
  var  
      ConnectionPointContainer:   IConnectionPointContainer;  
      ConnectionPoint:   IConnectionPoint;  
  begin  
      Result   :=   E_FAIL;  
      try  
          ConnectionPointContainer   :=   GroupIf   as   IConnectionPointContainer;  
      except  
          ConnectionPointContainer   :=   nil;  
      end;  
      if   ConnectionPointContainer   <>   nil   then  
      begin  
          Result   :=   ConnectionPointContainer.FindConnectionPoint(IID_IOPCDataCallback,  
              ConnectionPoint);  
          if   Succeeded(Result)   and   (ConnectionPoint   <>   nil)   then  
          begin  
              Result   :=   ConnectionPoint.Unadvise(AsyncConnection);  
          end;  
      end;  
  end;  
   
  //   wrapper   for   IOPCSyncIO.Read   (single   item   only)  
  function   ReadOPCGroupItemValue(GroupIf:   IUnknown;   ItemServerHandle:   OPCHANDLE;  
                      var   ItemValue:   string;   var   ItemQuality:   Word):   HResult;  
  var  
      SyncIOIf:   IOPCSyncIO;  
      Errors:   PResultList;  
      ItemValues:   POPCITEMSTATEARRAY;  
  begin  
      Result   :=   E_FAIL;  
      try  
          SyncIOIf   :=   GroupIf   as   IOPCSyncIO;  
      except  
          SyncIOIf   :=   nil;  
      end;  
      if   SyncIOIf   <>   nil   then  
      begin  
          Result   :=   SyncIOIf.Read(OPC_DS_CACHE,   1,   @ItemServerHandle,   ItemValues,  
                                                          Errors);  
          if   Succeeded(Result)   then  
          begin  
              Result   :=   Errors[0];  
              CoTaskMemFree(Errors);  
              ItemValue   :=   VarToStr(ItemValues[0].vDataValue);  
              ItemQuality   :=   ItemValues[0].wQuality;  
              VariantClear(ItemValues[0].vDataValue);  
              CoTaskMemFree(ItemValues);  
          end;  
      end;  
  end;  
   
  //   wrapper   for   IOPCSyncIO.Write   (single   item   only)  
  function   WriteOPCGroupItemValue(GroupIf:   IUnknown;   ItemServerHandle:   OPCHANDLE;  
                      ItemValue:   OleVariant):   HResult;  
  var  
      SyncIOIf:   IOPCSyncIO;  
      Errors:   PResultList;  
  begin  
      Result   :=   E_FAIL;  
      try  
          SyncIOIf   :=   GroupIf   as   IOPCSyncIO;  
      except  
          SyncIOIf   :=   nil;  
      end;  
      if   SyncIOIf   <>   nil   then  
      begin  
          Result   :=   SyncIOIf.Write(1,   @ItemServerHandle,   @ItemValue,   Errors);  
          if   Succeeded(Result)   then  
          begin  
              Result   :=   Errors[0];  
              CoTaskMemFree(Errors);  
          end;  
      end;  
  end;

没看完,太长。。。。

我把问题换换吧,怎么用delphi做opc服务器

delphi怎么做opc?  
 

帮你顶!看花眼了!

应该有这方面的资料,从网上搜一下吧

完全看不懂

我有源代码,发给你



--------------------------
新闻:上海最快3月底推TD上网本
导航:博客园首页  知识库  新闻  招聘  社区  小组  博问  网摘  找找看
阅读(862) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~