C# DLLImport converted to VB.NET DLLImport...what am I missing?

richard picture richard · Jul 24, 2012 · Viewed 9.1k times · Source

In C# I have this:

[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
    public static extern IntPtr GetDesktopWindow();

I tried to convert to VB.NET thus:

<DllImport("user32.dll", EntryPoint:="GetDesktopWindow")>
Function GetDesktopWindow() As IntPtr
End Function

But I am getting an error... "Imports System.Runtime.InteropServices.DllImportAttribute cannot be applied to instance method."

Can some explain what I need to do to fix this, and even better, tell me WHY?

Thanks!

Answer

Cody Gray picture Cody Gray · Jul 24, 2012

You forgot to convert the static keyword from the C# declaration to VB.NET. That's what the error message is telling you. Unless you have a static method, you're declaring an instance method, and the DllImportAttribute cannot be applied to an instance method.

The VB.NET equivalent of static is Shared. So your declaration should look like this:

<DllImport("user32.dll", EntryPoint:="GetDesktopWindow")>
Shared Function GetDesktopWindow() As IntPtr
End Function

I feel compelled to point out a couple of other things:

  • It's unnecessary to specify the EntryPoint when your function declaration has the same name. Not that it hurts anything to do so anyway, but I feel that it keeps down duplication and reduces the chances of error if you omit it.
  • P/Invoke declarations like this should generally go into a static class with a name like NativeMethods (StyleCop enforces this guideline). In VB.NET, static classes are called modules. So it would look like this:

    Module NativeMethods
        <DllImport("user32.dll")>
        Shared Function GetDesktopWindow() As IntPtr
        End Function
    End Module
    
  • In older versions of VB (pre-VB 10, shipped with VS 2010), you needed line continuation characters in order to break up function declarations onto multiple lines. Those ugly warts make it look like this:

    Module NativeMethods
        <DllImport("user32.dll")> _
        Shared Function GetDesktopWindow() As IntPtr
        End Function
    End Module
    

And finally, be very careful about how you use the desktop window returned by the GetDesktopWindow function! Lots of people abuse it, and most of the time when I see people trying to retrieve a handle to it, that's a sign that they're already doing it wrong. (Not saying you are, since I can't see the rest of your code, just something to be aware of!)