Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. Exception during assignment operation to a COM object - "Attempted to read or write protected memory"

Exception during assignment operation to a COM object - "Attempted to read or write protected memory"

Scheduled Pinned Locked Moved COM
comsysadminperformancehelptutorial
9 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    asr1122
    wrote on last edited by
    #1

    Hi. I have a piece of code at client side which calls a method of a COM server to create and return an object. While trying to assign values to data members of this object, I get the following exception - "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." I don't have much exposure to COM so am quite clueless as to how to solve this. Parts of the source are pasted below. interface _ICallInfo: IDispatch { [ propget, id(1), helpstring("Call ID") ] HRESULT CallId([out, retval] LONG *pVal); [ propput, id(1), helpstring("Call ID") ] HRESULT CallId([in] LONG nCallId); [ propget, id(2), helpstring("Barge Call") ] HRESULT CallType([out, retval] LONG *nCallType); [ propput, id(2), helpstring("Call Type") ] HRESULT CallType([in] LONG nCallType); }; dispinterface _IApplication { [ id(3), helpstring("method CreateCallInfo") ] HRESULT CreateCallInfo([out]_ICallInfo** piResult); }; public void foo() { CallInfo callInfo = null; CreateCallInfo(out callInfo); try { callInfo.CallId = this.CallId; callInfo.CallType = (int)this.CallType; } catch (Exception ex) { //Exception here } } Any help will be appreciated. Thanks.

    L 1 Reply Last reply
    0
    • A asr1122

      Hi. I have a piece of code at client side which calls a method of a COM server to create and return an object. While trying to assign values to data members of this object, I get the following exception - "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." I don't have much exposure to COM so am quite clueless as to how to solve this. Parts of the source are pasted below. interface _ICallInfo: IDispatch { [ propget, id(1), helpstring("Call ID") ] HRESULT CallId([out, retval] LONG *pVal); [ propput, id(1), helpstring("Call ID") ] HRESULT CallId([in] LONG nCallId); [ propget, id(2), helpstring("Barge Call") ] HRESULT CallType([out, retval] LONG *nCallType); [ propput, id(2), helpstring("Call Type") ] HRESULT CallType([in] LONG nCallType); }; dispinterface _IApplication { [ id(3), helpstring("method CreateCallInfo") ] HRESULT CreateCallInfo([out]_ICallInfo** piResult); }; public void foo() { CallInfo callInfo = null; CreateCallInfo(out callInfo); try { callInfo.CallId = this.CallId; callInfo.CallType = (int)this.CallType; } catch (Exception ex) { //Exception here } } Any help will be appreciated. Thanks.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      1. What is the actual code for the following function?

      HRESULT CreateCallInfo([out]_ICallInfo** piResult);

      2. Why do you not check the result of your CreateCallInfo(out callInfo); call to see whether your object was actually created?

      It's time for a new signature.

      A 1 Reply Last reply
      0
      • L Lost User

        1. What is the actual code for the following function?

        HRESULT CreateCallInfo([out]_ICallInfo** piResult);

        2. Why do you not check the result of your CreateCallInfo(out callInfo); call to see whether your object was actually created?

        It's time for a new signature.

        A Offline
        A Offline
        asr1122
        wrote on last edited by
        #3

        Richard MacCutchan wrote: 1. What is the actual code for the following function? HRESULT CreateCallInfo([out]_ICallInfo** piResult); void CApplication::CreateCallInfo(IDispatch** piResult) { CCmdTarget* pTarget = new CCallInfo(); *piResult = pTarget->GetIDispatch(TRUE); } I am not sure if you need the source for CCallInfo class so skipping that. Richard MacCutchan wrote: 2. Why do you not check the result of your CreateCallInfo(out callInfo); call to see whether your object was actually created? Sorry about skipping that part. I actually do check for that and I am a 100% sure that 'callInfo' has been created successfully. The thing is we have been using 'Reflection' to copy data to 'callInfo' till date. Now we plan to remove that as we are finding it a bit heavy. Please do let me know if more information is required.

        L V 2 Replies Last reply
        0
        • A asr1122

          Richard MacCutchan wrote: 1. What is the actual code for the following function? HRESULT CreateCallInfo([out]_ICallInfo** piResult); void CApplication::CreateCallInfo(IDispatch** piResult) { CCmdTarget* pTarget = new CCallInfo(); *piResult = pTarget->GetIDispatch(TRUE); } I am not sure if you need the source for CCallInfo class so skipping that. Richard MacCutchan wrote: 2. Why do you not check the result of your CreateCallInfo(out callInfo); call to see whether your object was actually created? Sorry about skipping that part. I actually do check for that and I am a 100% sure that 'callInfo' has been created successfully. The thing is we have been using 'Reflection' to copy data to 'callInfo' till date. Now we plan to remove that as we are finding it a bit heavy. Please do let me know if more information is required.

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          I notice that the declaration of the CreateCallInfo shows it to return a HRESULT but the implementation is void so there is no way you can check the return value. Also within this function you have no error checks. It may be best to add some more code into your catch block to try and identify which memory pointer is invalid. If this is easily reproducible then the debugger should be the way to go.

          It's time for a new signature.

          A 2 Replies Last reply
          0
          • L Lost User

            I notice that the declaration of the CreateCallInfo shows it to return a HRESULT but the implementation is void so there is no way you can check the return value. Also within this function you have no error checks. It may be best to add some more code into your catch block to try and identify which memory pointer is invalid. If this is easily reproducible then the debugger should be the way to go.

            It's time for a new signature.

            A Offline
            A Offline
            asr1122
            wrote on last edited by
            #5

            Caught! I actually don't do that but I knew that there is no problem in creating the 'callInfo' object as I was checking that using the debugger (always reproducible if I don't use reflection to assign values). This is how the function looks like using reflection (which works without a hitch) -

            public CallInfo CreateCallInfo(ApplicationClass appRoot)
            {
            CallInfo callInfo = null;

                    //callInfo = new CallInfo();
                    appRoot.CreateCallInfo(out callInfo);
                    
                    try
                    {                
                        Type typeCallInfo = typeof(CallInfo);
                        Type typeUCOMCallData = typeof(UCOMCallData);
            
                        object\[\] objValue = new object\[1\];
                        foreach (PropertyInfo pi in typeUCOMCallData.GetProperties())
                        {
                            objValue\[0\] = typeUCOMCallData.GetProperty(pi.Name).GetValue(this, null);
                            typeCallInfo.InvokeMember(pi.Name, 
                                                      BindingFlags.SetProperty, 
                                                      null, 
                                                      (CallInfo)callInfo, 
                                                      objValue);
                        }
                    }
                    catch (Exception ex)
                    {
                    }
            

            }

            Trying without reflection -

            public CallInfo CreateCallInfo(ApplicationClass appRoot)
            {
            CallInfo callInfo = null;

                    //callInfo = new CallInfo();
                    appRoot.CreateCallInfo(out callInfo);
                    
                    try
                    {                
                        //Type typeCallInfo = typeof(CallInfo);
                        //Type typeUCOMCallData = typeof(UCOMCallData);
            
                        //object\[\] objValue = new object\[1\];
                        //foreach (PropertyInfo pi in typeUCOMCallData.GetProperties())
                        //{
                        //    objValue\[0\] = typeUCOMCallData.GetProperty(pi.Name).GetValue(this, null);
                        //    typeCallInfo.InvokeMember(pi.Name, 
                        //                              BindingFlags.SetProperty, 
                        //                              null, 
                        //                              (CallInfo)callInfo, 
                        //                              objValue);
                        //}
            
                        callInfo.CallId = nCallId; //private member variable
                    }
                    catch (Exception ex)
                    {
                    }
            
                    return callInfo;
            

            }

            1 Reply Last reply
            0
            • L Lost User

              I notice that the declaration of the CreateCallInfo shows it to return a HRESULT but the implementation is void so there is no way you can check the return value. Also within this function you have no error checks. It may be best to add some more code into your catch block to try and identify which memory pointer is invalid. If this is easily reproducible then the debugger should be the way to go.

              It's time for a new signature.

              A Offline
              A Offline
              asr1122
              wrote on last edited by
              #6

              Trying to paste more information about the exception from the exception helper System.AccessViolationException was caught Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt." Source="WebAstra.Application.VoIP.UniversalCOMServer.Interop" StackTrace: at WebAstra.Application.VoIP.UniversalCOMServer.Interop._ICallInfo.set_CallId(Int32 pVal) at WebAstra.Application.VoIP.UniversalCOMServer.UCOMCallData.CreateCallInfo(ApplicationClass appRoot) Now the dispatch map for this in source is like:

              BEGIN_DISPATCH_MAP(CCallInfo, CCmdTarget)
              //There are many other entries as well
              DISP_PROPERTY_ID(CCallInfo, "CallId", dispidCallId, m_nCallId, VT_I4)
              END_DISPATCH_MAP()

              In the sources, I don't see any function of setting or getting values so I tried using DISP_PROPERTY_EX_ID instead of DISP_PROPERTY_ID with get and set functions but that didn't change anything. (my change which didn't change anything)

              DISP_PROPERTY_EX_ID(CCallInfo, "CallId", dispidCallId, GetCallId, SetCallId, VT_I4)

              Moreover in the interop, I do see the entry like this -

              [DispId(1)]
              int CallId { get; set; }

              Maybe that's because get and set methods have been declared in the IDL file (??). Thanks.

              L 1 Reply Last reply
              0
              • A asr1122

                Trying to paste more information about the exception from the exception helper System.AccessViolationException was caught Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt." Source="WebAstra.Application.VoIP.UniversalCOMServer.Interop" StackTrace: at WebAstra.Application.VoIP.UniversalCOMServer.Interop._ICallInfo.set_CallId(Int32 pVal) at WebAstra.Application.VoIP.UniversalCOMServer.UCOMCallData.CreateCallInfo(ApplicationClass appRoot) Now the dispatch map for this in source is like:

                BEGIN_DISPATCH_MAP(CCallInfo, CCmdTarget)
                //There are many other entries as well
                DISP_PROPERTY_ID(CCallInfo, "CallId", dispidCallId, m_nCallId, VT_I4)
                END_DISPATCH_MAP()

                In the sources, I don't see any function of setting or getting values so I tried using DISP_PROPERTY_EX_ID instead of DISP_PROPERTY_ID with get and set functions but that didn't change anything. (my change which didn't change anything)

                DISP_PROPERTY_EX_ID(CCallInfo, "CallId", dispidCallId, GetCallId, SetCallId, VT_I4)

                Moreover in the interop, I do see the entry like this -

                [DispId(1)]
                int CallId { get; set; }

                Maybe that's because get and set methods have been declared in the IDL file (??). Thanks.

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                I don't see anything in the above that offers a clue. My only suggestion is to step through the code with the debugger and trap where the exception occurs. You should then be able to see the actual memory that is causing the problem.

                It's time for a new signature.

                1 Reply Last reply
                0
                • A asr1122

                  Richard MacCutchan wrote: 1. What is the actual code for the following function? HRESULT CreateCallInfo([out]_ICallInfo** piResult); void CApplication::CreateCallInfo(IDispatch** piResult) { CCmdTarget* pTarget = new CCallInfo(); *piResult = pTarget->GetIDispatch(TRUE); } I am not sure if you need the source for CCallInfo class so skipping that. Richard MacCutchan wrote: 2. Why do you not check the result of your CreateCallInfo(out callInfo); call to see whether your object was actually created? Sorry about skipping that part. I actually do check for that and I am a 100% sure that 'callInfo' has been created successfully. The thing is we have been using 'Reflection' to copy data to 'callInfo' till date. Now we plan to remove that as we are finding it a bit heavy. Please do let me know if more information is required.

                  V Offline
                  V Offline
                  Vi2
                  wrote on last edited by
                  #8

                  asr1122 wrote:

                  void CApplication::CreateCallInfo(IDispatch** piResult) { CCmdTarget* pTarget = new CCallInfo(); *piResult = pTarget->GetIDispatch(TRUE); }

                  Return of IDispatch pointer is not equal to return of _ICallInfo pointer. IDispatch pointer does not have the CallId property (more clearly, the CallId get-property and CallId put-property), presented in _ICallInfo dual interface. You can heal this by: 1) replacing of "interface _ICallInfo: IDispatch" onto "dispinterface _ICallInfo" in IDL file; 2) replacing of "*piResult = pTarget->GetIDispatch(TRUE);" onto "*piResult = GetInterface(&__uuidof(_ICallInfo))" or "InternalQueryInterface(&__uuidof(_ICallInfo), piResult);" with acceptable casts.

                  With best wishes, Vita

                  A 1 Reply Last reply
                  0
                  • V Vi2

                    asr1122 wrote:

                    void CApplication::CreateCallInfo(IDispatch** piResult) { CCmdTarget* pTarget = new CCallInfo(); *piResult = pTarget->GetIDispatch(TRUE); }

                    Return of IDispatch pointer is not equal to return of _ICallInfo pointer. IDispatch pointer does not have the CallId property (more clearly, the CallId get-property and CallId put-property), presented in _ICallInfo dual interface. You can heal this by: 1) replacing of "interface _ICallInfo: IDispatch" onto "dispinterface _ICallInfo" in IDL file; 2) replacing of "*piResult = pTarget->GetIDispatch(TRUE);" onto "*piResult = GetInterface(&__uuidof(_ICallInfo))" or "InternalQueryInterface(&__uuidof(_ICallInfo), piResult);" with acceptable casts.

                    With best wishes, Vita

                    A Offline
                    A Offline
                    asr1122
                    wrote on last edited by
                    #9

                    Thanks for the suggestion. I couldn't make it work though. Decided to give up on this way of passing data. Looking at other simpler options. Thanks for the help.

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups