在VB程序中调用用VC++编写的DLL,其中有的函数参数涉及到指针,而VB不支持指针类型,各相关的书籍中只讲到可按引用(或者说按地址传递)的方式声明,但具体到调用该函数时,要获得这个地址将如何进行?
  比如:VC++编写的DLL中有如此函数
        BOOL Hik_PlayM4_InputData(Long nPort,PBYTE pBuf,DWORD nSize);
     说明:这是一个视频采集卡的SDK软件包中输入从卡上得到的数据流指定大小的数据缓冲区中。
     其中:nPort是通道号
           pBuf是缓冲区地址
           nSize是缓冲区大小
     请问:pBuf这个缓冲区地址在VB中如何来获得?

解决方案 »

  1.   

    假定有byte叔祖bt
    varptr(bt(0))就是bt得地址
      

  2.   

    假定有byte数组bt
    varptr(bt(0))就是bt得地址
      

  3.   

    注意,vb中的AddressOf 运算符可以获得地址。
    AddressOf
    一个一元运算符,它将其后面的过程的地址传递给一个 API 过程,该 API 过程在参数表对应位置中需要一个函数指针。
    语法:AddressOf procedurename
    必需的 procedurename 指定要传递的地址是哪一个过程的地址。这个过程必须是发出调用命令的工程中的一个标准模块模块里的一个过程。
    说明
    当一个过程的名称出现在一个参数列表中时,通常该过程已经被计算,并且该过程返回值的地址也会被传递。AddressOf 允许该过程的地址被传递给动态链接库 (DLL) 中的一个 Windows API 函数,而不是传递该过程的返回值。API 函数然后就可以使用这个地址来调用相应的 Basic 过程,这个过程就是我们所知道的回调。AddressOf 运算符只出现在对 API 过程的调用中。
    尽管可以使用 AddressOf 运算符在 Basic 过程之间传递过程指针,却不能通过这样的一个指针从 Basic 内部调用一个函数。这就是说,例如,一个使用 Basic 编写的类 不能使用这样的一个指针来回调自己的控制器。当使用 AddressOf 运算符在 Basic 内的过程之间传递一个过程的指针时,被调用过程的参数类型必须定义为 As Long。
    警告 如果不能完全理解函数回调的概念,则使用 AddressOf 运算符可能会导致意想不到的结果。必须理解回调的 Basic 部份是如何工作的,以及接受所传递的函数地址的 DLL 的代码是如何工作的。调试这样的交互操作是非常困难的,因为该程序和开发环境运行在相同的进程中。在某些情况下,系统的调试也许是不可能的。
    注意 可以使用 Microsoft Visual C++ (或者类似的工具)编译的 DLLs 来创建自己的回调函数原型。要使用 AddressOf 运算符来工作,您的原型必需使用 __stdcall 调用约定。缺省的调用约定 (__cdecl) 不能与 AddressOf 运算符一起工作。
    因为一个回调的调用程序不在用户自己的程序中,所以很重要的一点是要保证回调过程中的错误不被回传到调用者。可以通过把 On Error Resume Next 语句放置于回调过程的起始处来达到这个要求。
      

  4.   

    AddressOf 运算符示例
    下面的示例创建一个带有一个列表框的窗体,该列表框包含您的系统中的字体的按字母顺序排序的列表。
    要运行该示例,请创建一个带有一个列表框的窗体。窗体部分的代码如下:
    Option Explicit
    Private Sub Form_Load()
        Module1.FillListWithFonts List1
    End Sub
    把下面的代码放置到一个模块中。EnumFontFamilies 函数定义中的第三个参数是一个长整形,它代表一个过程。该参数必须包含这个过程的地址,而不是这个过程的返回值。在对 EnumFontFamilies 的调用中,第三个参数需要 AddressOf 运算符来返回 EnumFontFamProc 过程的地址,该过程是当调用 Windows API 函数,即 EnumFontFamilies 时提供的回调过程的名称。当把 AddressOf EnumFontFamProc 传递给 EnumFontFamilies 时, Windows 就会为系统中的每一个字体库调用一次 EnumFontFamProc。传递给 EnumFontFamilies 的最后一个参数指定用来显示信息的列表框。
    '字体枚举类型
    Public Const LF_FACESIZE = 32
    Public Const LF_FULLFACESIZE = 64
    Type LOGFONT
            lfHeight As Long
            lfWidth As Long
            lfEscapement As Long
            lfOrientation As Long
            lfWeight As Long
            lfItalic As Byte
            lfUnderline As Byte
            lfStrikeOut As Byte
            lfCharSet As Byte
            lfOutPrecision As Byte
            lfClipPrecision As Byte
            lfQuality As Byte
            lfPitchAndFamily As Byte
            lfFaceName(LF_FACESIZE) As Byte
    End TypeType NEWTEXTMETRIC
            tmHeight As Long
            tmAscent As Long
            tmDescent As Long
            tmInternalLeading As Long
            tmExternalLeading As Long
            tmAveCharWidth As Long
            tmMaxCharWidth As Long
            tmWeight As Long
            tmOverhang As Long
            tmDigitizedAspectX As Long
            tmDigitizedAspectY As Long
            tmFirstChar As Byte
            tmLastChar As Byte
            tmDefaultChar As Byte
            tmBreakChar As Byte
            tmItalic As Byte
            tmUnderlined As Byte
            tmStruckOut As Byte
            tmPitchAndFamily As Byte
            tmCharSet As Byte
            ntmFlags As Long
            ntmSizeEM As Long
            ntmCellHeight As Long
            ntmAveWidth As Long
    End Type' ntmFlags 段标志
    Public Const NTM_REGULAR = &H40&
    Public Const NTM_BOLD = &H20&
    Public Const NTM_ITALIC = &H1&'  tmPitchAndFamily 标志
    Public Const TMPF_FIXED_PITCH = &H1
    Public Const TMPF_VECTOR = &H2
    Public Const TMPF_DEVICE = &H8
    Public Const TMPF_TRUETYPE = &H4Public Const ELF_VERSION = 0
    Public Const ELF_CULTURE_LATIN = 0'  EnumFonts 掩码
    Public Const RASTER_FONTTYPE = &H1
    Public Const DEVICE_FONTTYPE = &H2
    Public Const TRUETYPE_FONTTYPE = &H4Declare Function EnumFontFamilies Lib "gdi32" Alias _
        "EnumFontFamiliesA" _
        (ByVal hDC As Long, ByVal lpszFamily As String, _ 
        ByVal lpEnumFontFamProc As Long, LParam As Any) As Long
    Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
    Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, _
        ByVal hDC As Long) As LongFunction EnumFontFamProc(lpNLF As LOGFONT, lpNTM As NEWTEXTMETRIC, _ 
        ByVal FontType As Long, LParam As ListBox) As Long
    Dim FaceName As String
    Dim FullName As String
        FaceName = StrConv(lpNLF.lfFaceName, vbUnicode)
        LParam.AddItem Left$(FaceName, InStr(FaceName, vbNullChar) - 1)
        EnumFontFamProc = 1
    End FunctionSub FillListWithFonts(LB As ListBox)
    Dim hDC As Long
        LB.Clear
        hDC = GetDC(LB.hWnd)
        EnumFontFamilies hDC, vbNullString, AddressOf EnumFontFamProc, LB
        ReleaseDC LB.hWnd, hDC
    End Sub