15 Replies Latest reply on Oct 2, 2012 6:37 AM by vkrejc

    Unregister PI points from event pipe in C++

    vkrejc

      Hi,

       

      I'm using event pipes for receiving new values from PI Server. Unfortunately I'm not able to unregister PI points from event pipe. Please review my code and let me know if I am doing something wrong. thank you!

       

      I am receiving this error:  Microsoft C++ exception: std::__non_rtti_object at memory location 0x0400c1dc on the line with HRESULT _hr = raw_RemoveSignUp(vtPrimary, vtSecondary); from pisdk.tli.

       

      Code:

       

       

       
      PISDK::_PointListPtr l_removeList;
      l_removeList.CreateInstance(__uuidof(PISDK::PointList));
      
      
      for(std::list<_bstr_t>::const_iterator iter = _tagNames.begin(); iter != _tagNames.end(); ++iter)
      {
           PISDK::PIPointPtr l_spPIPoint = m_spServer->PIPoints->GetItem(*iter);
                                    
           l_removeList->Add(l_spPIPoint);
      }
      
      PISDK::IEventPipe3Ptr l_spIep3 = m_spEvPipe;
      
      _variant_t l_values(l_removeList.GetInterfacePtr());
                
      HRESULT l_hr = l_spIep3->RemoveSignUp(l_values, NULL);
      

       

       

       

       

       

        • Re: Unregister PI points from event pipe in C++
          vkrejc

          I have the same issue with AddSignUp. I'm able to call this method with parameter PiPoint. When I try to enter PointList, I receive error.

           

          Code:

           

           

           

           

           
          const _variant_t l_values(l_newList.GetInterfacePtr());
          
          PISDK::IEventPipe3Ptr l_spIep3 = m_spEvPipe;
                         
          //PISDK::PIPointPtr l_spPIPoint = m_spServer->PIPoints->GetItem("SINUSOID");
          //_variant_t l_values(l_spPIPoint.GetInterfacePtr());
          
          HRESULT l_hr = l_spIep3->AddSignUp(l_values, NULL);
          

           

           

          Commented rows work.

           

          Thank for all your help.

           

           

           

           

            • Re: Unregister PI points from event pipe in C++
              hanyong

              Hi Vlad,

               

              How about something like:

              _PointListPtr ptList = spServer->GetPoints("tag='cd*'", NULL);

              EventPipePtr evtpipe = ptList->Data->EventPipe;

              IEventPipe2Ptr ievp2 = (IEventPipe2Ptr)evtpipe;

              _PointListPtr ptList2;
              ptList2.CreateInstance(__uuidof(PointList));
              ptList2->Add(spServer->PIPoints->GetItem("cdt158"));
              ptList2->Add(spServer->PIPoints->GetItem("cdm158"));

              _variant_t ptp;
              VariantInit (&ptp);
              V_VT (&ptp) = VT_DISPATCH;
              V_DISPATCH(&ptp) = ptList2;
               
              ievp2->RemoveSignUp(ptp, NULL);
                • Re: Unregister PI points from event pipe in C++
                  vkrejc

                  Hi Han,

                   

                  thanks for answer! I'm going to try it! I will let you know!

                   

                  Thanks

                    • Re: Unregister PI points from event pipe in C++
                      vkrejc

                      Unfortunately, I'm receiving still the same exception.

                       

                      Error:

                       

                      Unhandled exception at 0x7c812afb in wrap.exe: Microsoft C++ exception: std::__non_rtti_object at memory location 0x03d0c168..

                       

                      Code:

                       

                       

                       

                       

                       
                      PISDK::_PointListPtr l_removeList;
                      l_removeList.CreateInstance(__uuidof(PISDK::PointList));
                      
                      
                      for(std::list<_bstr_t>::const_iterator iter = _tagNames.begin(); iter != _tagNames.end(); ++iter)
                      {
                           PISDK::PIPointPtr l_spPIPoint = ((cPiServer*) m_server)->m_spServer->PIPoints->GetItem(*iter);
                                     
                                     
                           l_removeList->Add(l_spPIPoint);
                      }
                      
                      
                      _variant_t l_values;
                      VariantInit (&l_values);
                      V_VT (&l_values) = VT_DISPATCH;
                      V_DISPATCH(&l_values) = l_removeList;
                                
                      HRESULT l_hr = m_spEvPipe->RemoveSignUp(l_values, NULL);
                      

                       

                       

                       

                       

                       

                        • Re: Unregister PI points from event pipe in C++
                          hanyong

                          This is interesting, I've tried the code myself, and it works for in my environment. I even tried to do something wrong like removing signup for a PIPoint that wasn't in the original signup list, etc. Attached is the code snippet that I've tested.

                           

                          I did a quick search on the net about your error and this shows up: http://msdn.microsoft.com/en-us/library/fyf39xec%28VS.80%29.aspx

                           

                          This suggests that the exception happens when a pointer is not pointed to a valid object.... Perhaps we are looking at the wrong place?

                           

                           

                            • Re: Unregister PI points from event pipe in C++
                              andreas

                              the difference is the interface you are using, Han Yong is using IEventPipe2Ptr  while you are using IEventPipe3Ptr.

                                • Re: Unregister PI points from event pipe in C++
                                  vkrejc

                                  Hi, I will try your sample code and also change the interface.

                                   

                                  Thanks for hints!

                                    • Re: Unregister PI points from event pipe in C++
                                      andreas

                                      Vlad, one more comment. Your creation of a pointlist requires a roundtrip per tag. This could be time consuming. The GetPoints method of the PointList is not implemented. Depending on the size of the pointlist and the time required for server->getitem you might be faster by iterating through the pointlist and grabbing the pipoint from there.

                                        • Re: Unregister PI points from event pipe in C++
                                          vkrejc

                                          Hi,

                                           

                                          I tried to change interface IEventPipe3Ptr to IEventPipe2Ptr and still the same issue. I also tried to copy-paste Han's code to my program and also didn't work. I'm pretty sure that we are  looking on the correct place, because I ran this code in debug mode in VS and it stopped on the line with AddsignUp / RemoveSignUp.

                                           

                                          I guess that problem is somewhere in pointList, because I'm able to call AddSignUp / RemoveSignUp for one PIPoint. Now I'm calling these methods for each PIPoints. I'm not sure, how big is it performance issue..

                                           

                                          Andreas, I'm sorry, but I'm little bit confused from your last post. I'm not sure, what I'm doing bad. As input I receive list of tag names (strings). For each tag in this list I call method getItem("pointName") and then I add this point to the pointList. I don't know, what pointlist should I use for iterating?

                                           

                                          Thanks!

                                            • Re: Unregister PI points from event pipe in C++
                                              vkrejc

                                              Andreas,

                                               

                                              did you mean this approach?

                                               

                                              Create where clause with something like: "tag in ('name1', 'name2', 'name3')" and use it in GetPoints method? So I would have only one call to PI Server, right? I should received PointList, right?

                                               

                                              Thank you

                                              • Re: Unregister PI points from event pipe in C++
                                                andreas

                                                Hi Vlad,

                                                 

                                                never mind. I have tried both versions - getting the PIPoint object as a GetItem from the server as well as finding it in the PointList does not make a difference for me.

                                                 

                                                 

                                                 

                                                 

                                                 

                                                 

                                                  • Re: Unregister PI points from event pipe in C++
                                                    vkrejc

                                                    Thanks Andreas.  What is your opinion about AddSignUp calling for each PIPoint and using PointList? Is it the big difference from performance point of view?

                                                     

                                                    Thank you

                                                      • Re: Unregister PI points from event pipe in C++
                                                        andreas

                                                        Vlad - removing the pointlist should be a single roundtrip, while removing one by one will cause multiples roundtrips. In a brief test the following code took for removing ~2x ping time to the server:

                                                         
                                                                  IPointList2Ptr iP2 = spPointList;
                                                                  _PointListPtr spPointList2 = NULL;
                                                                  spPointList2.CreateInstance(__uuidof(PointList));
                                                                  spPointList2 = spServer->GetPoints((_bstr_t)"Tag='C*'", NULL);
                                                        
                                                                  StartCounter();
                                                                  _variant_t vtDispatch(spPointList2.GetInterfacePtr()); 
                                                                  iep2->RemoveSignUp(vtDispatch,NULL);
                                                                  iP2->Remove(&vtDispatch);
                                                                  std::cout << GetCounter() <<"\n";
                                                        
                                                         
                                                        

                                                         

                                                         

                                                        but note - getting the pointlist is not in the timing. The following code

                                                         
                                                                  StartCounter();
                                                                  for (int a = 1; a <= spPointList2->Count; a++) {
                                                                       _variant_t vtIdx;
                                                                       vtIdx = a;
                                                                       spPIPoint = spPointList2->GetItem(&vtIdx);
                                                                       _variant_t vtDispatch(spPIPoint.GetInterfacePtr()); 
                                                                       iep2->RemoveSignUp(vtDispatch,NULL);
                                                                       iP2->Remove(&vtDispatch);
                                                                  }
                                                                  std::cout << GetCounter() <<"\n";
                                                        

                                                         

                                                         

                                                        required ~ 2x Count x ping time.