Solved

Problem with accessing protected memory after creating delegate in VB.NET 2005

Posted on 2007-03-29
5
330 Views
Last Modified: 2007-11-27
I have taken some sample code from an application written in VB6.  I used the upgrade wizard to upgrade it to VB 2005.  It told me I needed to add a delegate for AddressOf WindowProc.

I followed the example from the help file and got the program to compile.  It works fine for a while, then after a while (the time varies) I receive an error that it "Attempted to read or write protected memory."  Text from error is below the code.

I don't understand what is happening. I'm a novice programmer and this doesn't make sense to me.  

What the program is doing (as I understand it) is that it uses a .dll to query a server.  This server sends back packets to this program asynchronously.  The program then receives the data packet and determines what to do with it from there.

Any help you can give me will be greatly appreciated.

'==================================================
'++++++++++++++Excerpt from Module1:

Declare Function CallWindowProc Lib "user32"  Alias "CallWindowProcA"(ByVal lpPrevWndFunc As Integer, ByVal hwnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

    '----------------The following 3 lines were modified from the initial build to accomodate a delegate:
    'Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As SubClassProcDelegate) As Integer
    Delegate Function SubClassProcDelegate(ByVal hw As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    '----------------
      Public Const GWL_WNDPROC As Short = -4
      Public lpPrevWndProc As Integer
      Public gHW As Integer
      
    '-----------------
    Function WindowProc(ByVal hw As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

        '---------------
        Dim intErrCode As Short
        Dim strTime As New VB6.FixedLengthString(40)
        If (uMsg = WM_RTB_MESSAGE) Then
            ' We are receiving a message.
            ' wParam tells us what it is.  We will display some
            ' message according to it.
            Select Case wParam
                Case 1
                    HelloVB.lblStatus.Text = "Trying primary"
                Case 2
                    HelloVB.lblStatus.Text = "Trying secondary"
                Case 3
                    HelloVB.lblStatus.Text = "Logon Completed"
                Case 4
                    'HelloVB.ShowRTBErrorMessage
                Case 5
                    ' lParam is the DataPacket ID.
                    ' Get the time out of the data packet.

                    intErrCode = RTBDataGetString(lParam, 0, 0, strTime.Value, 40)
                    HelloVB.lblData.Text = "Hello World, it's " & strTime.Value & "!"

                    ' Free the data packet
                    intErrCode = RTBFreePacket(lParam)
            End Select
        End If
        '-------------
        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
        '-------------
    End Function
'==================================================

'+++++++++++++Excerpt from Main Class Form

'UPGRADE_WARNING: Add a delegate for AddressOf WindowProc Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="E9E157F7-EF0C-4016-87B7-7D7FBBC6EE08"'
        '-----------
        lpPrevWndProc = SetWindowLong(Me.Handle.ToInt32, GWL_WNDPROC, AddressOf WindowProc)

        '-----------' Create the query

'==================================================
Error information
************** Exception Text **************
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
   at System.Windows.Forms.Form.DefWndProc(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ContainerControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmSysCommand(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
0
Comment
Question by:robbid
  • 2
  • 2
5 Comments
 

Author Comment

by:robbid
Comment Utility
Here is some additional information about the error:

A callback was made on a garbage collected delegate of type 'Project1!Project1.Module1+SubClassProcDelegate::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
0
 
LVL 41

Accepted Solution

by:
graye earned 500 total points
Comment Utility
Take a look at this introductory article about Delegates and the AddressOf operator...   It has some downloadable VB.Net source code examples that might be if help

http://home.hot.rr.com/graye/Articles/Delgates_AdressOf.htm
0
 

Author Comment

by:robbid
Comment Utility
Thanks,
This article helps me understand the process a little better.  I still don't understand why the delegate is being collected, though.  I think I might try re-writing the code myself (using information from the article you provided and some others) and see what happens.
0
 
LVL 41

Assisted Solution

by:graye
graye earned 500 total points
Comment Utility
I don't see where the value for lpPrevWndProc is originally set.   It appears to me that when SetWindowLong is first called from the "Main Class Form" there is no value for lpPrevWndProc.   It only get's set after SetWindowLong has completed.

But a break on this statement and see what the value of lpPrevWndProc is

        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now