Results 1 to 1 of 1

Thread: LoadLibrary demo. Calling DLL functions using LoadLibrary and GetProcAddress.

  1. #1

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    LoadLibrary demo. Calling DLL functions using LoadLibrary and GetProcAddress.

    Nothing too exciting here. This is just some code I wrote to demonstrate how to call a function in a DLL through the use of LoadLibrary and GetProcAddress.

    I was doing some experiments for this thread and I found it very interesting that it was hard to find a proper or complete VB.Net sample that shows how to use LoadLibrary so I decided to contribute a sample myself.

    Here:-
    Code:
    Imports System.Runtime.InteropServices
    Public Class Form1
    
        Private Delegate Function GetWindowRectDelegate(ByVal hWnd As IntPtr, ByRef lpRect As WindowsAPI.RECT) As Boolean
    
        'Define a delegate type for the GetWindowRect function from the User32.Dll library.
        Private GetWndRect As GetWindowRectDelegate
    
        'Handle to the User32.Dll loaded into our process's address space by LoadLibrary.
        'We need to keep this handle so we can free the library when we are done with it.
        Private _hModule As IntPtr
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'Loads our DLL into the application's address space
            InitLib()
    
            'Obtain a delegate to call User32's GetWindowRect function from .Net. and assign
            'it to a delegate type variable. We can then use this variable to call the function.
            GetWndRect = GetFunctionFromLibrary(Of GetWindowRectDelegate)(_hModule, "GetWindowRect")
        End Sub
    
        Private Sub InitLib()
            'Loads User32.Dll into the address space of our application
            _hModule = WindowsAPI.LoadLibraryW("User32.dll")
    
            'Checks to make sure the LoadLibrary call succeeded
            If _hModule = IntPtr.Zero Then
                Throw New Exception($"LoadLibrary failed with error {Marshal.GetLastWin32Error.ToString}")
            End If
        End Sub
    
        Private Shared Function GetFunctionFromLibrary(Of T)(ByVal hModule As IntPtr, ByVal funcName As String) As T
            Dim ptr As IntPtr
    
            'Try to obtain a raw function pointer to the function from the DLL
            ptr = WindowsAPI.GetProcAddress(hModule, funcName)
    
            'Make sure it succeeded
            If ptr = IntPtr.Zero Then
                Throw New Exception($"Failed to obtain address of function '{funcName}'. Error code {Marshal.GetLastWin32Error.ToString}")
            End If
    
            'Convert the raw function pointer to a .Net delegate so we can call it
            Return Marshal.GetDelegateForFunctionPointer(Of T)(ptr)
        End Function
    
        Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            UpdateDisplay()
        End Sub
    
        Private Sub Form1_Move(sender As Object, e As EventArgs) Handles Me.Move
            UpdateDisplay()
        End Sub
    
        Private Sub UpdateDisplay()
            Dim r As WindowsAPI.RECT
    
            'Make sure we do have a function to call from the delegate
            'variable.
            If GetWndRect IsNot Nothing Then
    
                'Call User32's GetWindowRect function through our .Net delegate 
                GetWndRect(Me.Handle, r)
    
                Me.Text = $"Left = {r.Left.ToString}, Top = {r.Top.ToString}, Right = {r.Right.ToString}, Bottom = {r.Bottom.ToString}"
            End If
    
        End Sub
    
        Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
            If Not WindowsAPI.FreeLibrary(_hModule) Then
                Throw New Exception("FreeLibrary call failed.")
            End If
        End Sub
    End Class
    
    Public Class WindowsAPI
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure RECT
            Public Left As Integer
            Public Top As Integer
            Public Right As Integer
            Public Bottom As Integer
        End Structure
    
    
        <DllImport("kernel32.dll")>
        Public Shared Function LoadLibraryW(<MarshalAs(UnmanagedType.LPWStr)> ByVal lpLibFileName As String) As IntPtr
        End Function
    
    
        'Notice a very important detail here, which is, we MUST marshal lpProcName as
        'an ANSI String. There is no wide version of GetProcAddress for some reason.
        <DllImport("kernel32.dll")>
        Public Shared Function GetProcAddress(ByVal hModule As IntPtr,
                                               <MarshalAs(UnmanagedType.LPStr)> ByVal lpProcName As String) As IntPtr
        End Function
    
        <DllImport("Kernel32.dll")>
        Public Shared Function FreeLibrary(ByVal hLibModule As IntPtr) As Boolean
        End Function
    
    End Class
    Create a new WinForms VB.Net project, double click Form1 and place the above code there. Run the application and move/resize the form. It's title bar should be constant updating with information on the size and location of the Form on the screen. The demo shows how to call the User32 DLL function GetWindowRect using LoadLibrary and GetProcAddress and the data in the title bar is obtained from calling GetWindowRect in this manner.

    Have fun.
    Last edited by Niya; Apr 6th, 2023 at 10:38 AM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width