如何在 VB.NET 中使用 <DllImport>?

Posted

技术标签:

【中文标题】如何在 VB.NET 中使用 <DllImport>?【英文标题】:How to use <DllImport> in VB.NET? 【发布时间】:2011-01-14 20:19:12 【问题描述】:

我应该如何 DLLImport VB.NET 中的东西?一个例子是:

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer

End Function

如果我把它放在一个类或其他地方,我会得到“DLLimport is not defined”我正在使用Visual Studio 2008Professional

【问题讨论】:

【参考方案1】:

您必须将Imports System.Runtime.InteropServices 添加到源文件的顶部。

或者,您可以完全限定属性名称:

<System.Runtime.InteropService.DllImport("user32.dll", _
    SetLastError:=True, CharSet:=CharSet.Auto)> _

【讨论】:

你有没有关于 Visual basic 2015 的书,只讲如何使用任何类型的 System.Runtime.InteropService.DllImport 成为它的大师?【参考方案2】:
Imports System.Runtime.InteropServices

【讨论】:

【参考方案3】:

我在 pinvoke.net 上的 getwindowtext (user32) 中看到,您可以放置​​ MarshalAs 语句来声明 StringBuffer 等效于 LPSTR。

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Ansi)> _
Public Function GetWindowText(hwnd As IntPtr, <MarshalAs(UnManagedType.LPStr)>lpString As System.Text.StringBuilder, cch As Integer) As Integer
End Function

【讨论】:

【参考方案4】:

我知道这个问题已经得到解答,但这里有一个示例供尝试在 vb 项目中使用 SQL Server 类型的人使用:

            Imports System
            Imports System.IO
            Imports System.Runtime.InteropServices

            Namespace SqlServerTypes
                Public Class Utilities



                    <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
                    Public Shared Function LoadLibrary(ByVal libname As String) As IntPtr

                    End Function

                    Public Shared Sub LoadNativeAssemblies(ByVal rootApplicationPath As String)
                        Dim nativeBinaryPath = If(IntPtr.Size > 4, Path.Combine(rootApplicationPath, "SqlServerTypes\x64\"), Path.Combine(rootApplicationPath, "SqlServerTypes\x86\"))
                        LoadNativeAssembly(nativeBinaryPath, "msvcr120.dll")
                        LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial140.dll")
                    End Sub

                    Private Shared Sub LoadNativeAssembly(ByVal nativeBinaryPath As String, ByVal assemblyName As String)
                        Dim path = System.IO.Path.Combine(nativeBinaryPath, assemblyName)
                        Dim ptr = LoadLibrary(path)

                        If ptr = IntPtr.Zero Then
                            Throw New Exception(String.Format("Error loading 0 (ErrorCode: 1)", assemblyName, Marshal.GetLastWin32Error()))
                        End If
                    End Sub
                End Class
            End Namespace

【讨论】:

回想起来,很抱歉在某种程度上劫持了这个线程,尽管这段代码解决了几个问题和要点,它的主要目的是让 ReportViewer 和 SqlServerTypes 在旧的 VB 项目中工作,并且一切正常。但我觉得我认为应该调用内核 dll 的已存根的 LoadLibrary 函数无法正常工作,因此 ReportViewer 可能没有使用该函数。 我很高兴你做到了!我在尝试完全按照您发布的内容进行操作时遇到了这个问题。谢谢【参考方案5】:

你也可以试试这个

Private Declare Function GetWindowText Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer

我总是使用 Declare Function 而不是 DllImport... 它更简单,它更短并且做同样的事情

【讨论】:

使用 Declare 语句不能做很多事情。您无法使用任何互操作属性。老实说,这是遗留的 VB 6 语法,我认为所有新的 VB.NET 代码都应该使用标准的 .NET 语法编写。 嗯,你说得对,但我是一个懒惰的程序员,所以我总是尽量选择最短的 :) 对于我的项目,这个总是帮助我

以上是关于如何在 VB.NET 中使用 <DllImport>?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VB.Net 的虚拟键语句中使用变量

如何在 VB.NET 中使用 protobuf-net 添加枚举?

在 VB.net 中,如何保存对 app.config 的更改

如何在 vb.net 中解析一串 xml

如何在 vb .net 中获取任何已连接打印机的型号

如何从 VB.NET 中的 XML 文件构建唯一的树结构