【问题标题】:How to use <DllImport> in VB.NET?如何在 VB.NET 中使用 <DllImport>?
【发布时间】: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

【问题讨论】:

    标签: vb.net dllimport


    【解决方案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 语法编写。
        • 嗯,你说得对,但我是一个懒惰的程序员,所以我总是尽量选择最短的 :) 对于我的项目,这个总是帮助我
        猜你喜欢
        • 2019-11-26
        • 2013-10-27
        • 2010-10-30
        • 2012-07-22
        • 2011-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多