StrPtr你看一下这篇文章,一定不会令你失望http://www.csdn.net/develop/read_article.asp?id=12675

解决方案 »

  1.   

    Advanced Visual Basice》是阐述VB高级编程技巧的一本好书
    本文原文:http://www.devx.com/premier/mgznarch/vbpj/2000/02feb00/mc0200/mc0200.asp
    (要先注册成premier用户)
    本文配套代码:
    http://www.devx.com/free/mgznarch/vbpj/code/2000/02feb00/vb0002mc_p.zip
    关键字:函数指针,COM、对象、接口,vTalbe,VB汇编,动态DLL调用。
    级别:高级
    要求:了解VB对象编程,了解汇编。                          调用函数指针
        通过使用函数指针,我们能够动态地在代码中插入不同行为的函数,从而使代码拥有动态改变自身行为的能力。作者:Matther Curland
    要求:使用本文的示例代码,你需要VB5或VB6的专业版或企业版。
        从Visual Basic 5.0开始Basic语言引入了一个重要的特性:AddressOf运算符。这个运算符能够让VB程序员直接体会到将自己的函数指针送出去的快感。比如我们在VB里就能够得到系统字体的列表,我们能够通过标准的API调用来进行子类化。一句话,我们终于可以象文档里所说的那样来使用Win32 API了。
        不过,这个新玩具只能给我们带来短暂的快感,因为这个礼物并不完整。我们可以送出函数指针,但却没人能将函数指针送给我们。事实上,我们甚至不能给我们自己送函数指针,这使我们不能够体验送礼的真正乐趣(译者:呵呵,光送礼却不能收礼的确没趣)。AddressOf让我们看到了广袤天地的一角,但是VB却不让我们全面地探索它,因为VB根本就不让我们调用函数指针,我们只能提供函数指针(译者:可以先将函数指针送给API,然后让API回调自已的函数指针来完成函数指针调用的功能,但这还是要先把礼物送给别人)。其实,我们能够自己来实现调用函数指针的功能,我们可以手工将一个对COM接口的vTable绑定调用变成一个函数指针调用。最妙的是:我们能够在纯VB里写出调用函数指针的代码,不需要任何辅助的DLL。    告诉编译器函数指针是什么样子,是使VB能够调用任何函数的关键。将参数类型和返回值类型交给VB编译器,让编译器将我们的函数调用编译到我们的程序里,这样程序才能在运行时知道怎样去定位函数。在程序被编译后,一个函数就是内存里一串汇编字节流,通过CPU解释执行而形成我们的程序。调用一个函数指针,首先需要程序获得指向这个函数字节流的指针,再通过x86汇编指令call将当前指令指针(译注:即x86汇编里的IP寄存器)转到函数所在的字节流上。在函数完成后,再用ret指令返回给调用此函数的程序来继续操作。    我下面将要提到的方法,利用了VB自己的函数调用方式,所以我先来解释一下VB是怎样来实现函数调用的。VB内部使用三种函数指针,但是,在本质上,不论VB是如何来定位这几类函数指针,调用它们的方法却是一样的。VB编译器必须知道准确的函数原型才能生成调用函数的代码。    第一类,最常见的函数指针类型,就是VB用来调用函数的普通指针,这样的函数定义在标准模块内(或类模块里的友元函数和私有函数)。调用友元函数和私有函数时,调用指令定位在当前指令指针的一个偏移地址处,或者先跳到一个记录着函数位置的查找表里,再跳到函数内(译者:即先"Call 绝对地址"跳到一个跳转表内,表里的每个入口都是一个"Jmp"到函数)。这些函数都在同一个工程内,联结器总是将所有的模块联结在一起,所以总是知道在内存何处能够找到VB内部函数,因此转移控制到内部函数时,其运行时开销是很少的。VB对某些函数指针的调用却困难得多
        对于另两类函数指针,VB必须在运行时进行额外的工作才能够找出它们。
        第二类,VB调用一个COM对象接口里的方法。我们可能认为建立COM对象的工作是相当复杂的,如果完全用VB来为我们建造COM的所有组成部分的话,但事实上并不是这样。按照COM的二进制标准,一个COM对象是一个指针,这个指针指向一个结构,这个特定结构的第一个元素是一个指向函数指针数组的指针。这个函数指针数组(又叫虚拟函数表,简称vTable)里的前三个指针,一定是标准QueryInterface,AddRef,Release函数。vTable里接下来的函数符合给定的COM对象接口定义里的函数定义
      

  2.   

    Objptr            返回对象的地址
    varptr            返回变体型变量的地址
    strptr            返回字符型变量的址址
    VarPtrArray      返回数组变量的址址
    VarPtrStringArray 返回字符数组变量的址址
    用于获取变量地址,是函数
    AddressOf,通常只用于回调,是运算符
    作为参数,如果你用的是地址,那么通过byval可以得到地址本身;通过byfef得到的是地址的地址
      

  3.   

    Object型差不多就是指针http://go6.163.com/910grtd/vb/wdzp/LineTool.htm
    一个画线工具的程序
    使用了链表方式存储端点数据
      

  4.   

    VB中使用指针上INTRODUCTION Something that C++ programmers have long been using is the pointer. These magical creatures are variables that literally hold memory locations. This means that instead of holding content, the variable points to a memory location (that is usually a variable) that contains data. I, not being fluent in C++, am not sure if C++ allows you to modify the value of a pointer, but if you could, you would instantly change the memory location that the pointer points to! But enough talk. Let's begin. ADVANTAGES & DISADVANTAGES OF POINTERS Before we delve into pointers, I would like to discuss why we should use pointers. After all, that's why we have ByRef. Well, one reason is that using pointers reduces memory consumption, and increases performance and efficiency. For example, passing a variable using ByVal uses a lot more memory than ByRef, because ByVal actually forces VB to create a new variable, and copy the contents of the original variable into the new one. But if we already have ByRef, why venture into using pointers? Well, pointers are flexible. Change the memory location the pointer points to, and the pointer points to that location, and using the Win32 API function CopyMemory will allow us to implant the contents of that memory location into the variable of our choice. In fact, some other Win32 API functions strictly require the use of memory locations! At the same time, pointers have disadvantages as well. You trade performance for stability. Your programs become harder to read, maintain, and less stable if you switch to using pointers. For example, you might accidentally point to a memory location that isn't in use by your program! You also leave VB's safe and cozy debugging environment and enter the crash zone. VB won't tell you that a pointer points to a memory location out of your program's memory bounds, and you will only be alerted by either a variable containing nothing, or a crash. It took me at least 2 hours staring at my demo app (details later) until I found out why it didn't work. So if you're gonna use pointers, good luck! DECLARING A POINTER Before we can use a pointer, we need to declare it first. A function that has long been shrouded in secrecy is the VarPtr function. It used to be in early versions of VB, but it was available only as an API call. Now, it is part of the VB language. Here's how you use it: Dim F as Integer 
    Dim L as Long F = 4 
    L = VarPtr(F) F is the name of the variable, and L, after calling VarPtr, contains the memory location of the variable. You can edit the value if you want. 
           以上代码来自: SourceCode Explorer(源代码数据库)
               复制时间: 02-6-4 18:05:54
               当前版本: 1.0.682
                   作者: Shawls
               个人主页: Http://Shawls.Yeah.Net
                 E-Mail: [email protected]
                     QQ: 9181729
      

  5.   

    VB中使用指针中USING A POINTER There are many ways to use a pointer. One way is to hand it over to a Win32 API call such as CopyMemory. This is the Declare statement for CopyMemory: Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Destination and Source can either be a variable (use ByRef) or a memory location (use ByVal). For example: CopyMemory ByVal TML, ByVal SML, 2 'Or CopyMemory NewNum, Num, 2 Here, TML and SML are pointers, and NewNum and Num are the variables they point to, respectively. Note that you use ByVal when using pointers, and ByRef (default) when using variable names. You can even mix the two, like this: CopyMemory ByVal TML, Num, 2 CopyMemory NewNum, ByVal SML, 2 Use the first one if you know the variable name of the source, and use the second one if you know the variable name of the destination. The Length argument specifies the number of bytes that you want to be transferred. I use 2, because there are two bytes in an integer (the last time I checked). I would really appreciate it if someone sends me a table listing the amount of bytes each data type in VB takes up. EXAMPLE My demo program is finally out of the infirmary. It took about a minute to make, and 1hour, 59 minutes to debug. All it does is prompt you for a number, then it uses CopyMemory to copy the value to another variable using variable pointers. Check it out! It is quite simple, and I know it isn't the best example around. I was originally going to make a sorting program, but it proved too difficult to debug. So this is what I used instead. The first step I took was create the project structure, which consists of a project (duh), a form, and a module. The code module contains the Win32 API call to CopyMemory. The form consists of a few labels; I won't cover them here because you can check the code. I'll then dissect the code for the form one block at a time. Private Sub cmdTest_Click() Please don't tell me you don't know what this does! Dim Num As Integer   'Source Variable 
    Dim NewNum As Integer 'Target variable 
    Dim SML As Long   'Source Memory Location 
    Dim TML As Long   'Target Memory Location I declared the variables. We're nearing the meat of the program! 'Error Handling 
    If Not IsNumeric(txtVal.Text) Then 
      MsgBox "X not numeric!" 
      Exit Sub 
    End If 
    If Val(txtVal.Text) > 32767 Then 
      MsgBox "X must be less than 32767!" 
      Exit Sub 
    End If 
    If Val(txtVal.Text) < -32768 Then 
      MsgBox "X must be greater than -32768!" 
      Exit Sub 
    End If 'Assign values 
    Num = Val(txtVal.Text) 
    NewNum = 0 
           以上代码来自: SourceCode Explorer(源代码数据库)
               复制时间: 02-6-4 18:06:25
               当前版本: 1.0.682
                   作者: Shawls
               个人主页: Http://Shawls.Yeah.Net
                 E-Mail: [email protected]
                     QQ: 9181729VB中使用指针中USING A POINTER There are many ways to use a pointer. One way is to hand it over to a Win32 API call such as CopyMemory. This is the Declare statement for CopyMemory: Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Destination and Source can either be a variable (use ByRef) or a memory location (use ByVal). For example: CopyMemory ByVal TML, ByVal SML, 2 'Or CopyMemory NewNum, Num, 2 Here, TML and SML are pointers, and NewNum and Num are the variables they point to, respectively. Note that you use ByVal when using pointers, and ByRef (default) when using variable names. You can even mix the two, like this: CopyMemory ByVal TML, Num, 2 CopyMemory NewNum, ByVal SML, 2 Use the first one if you know the variable name of the source, and use the second one if you know the variable name of the destination. The Length argument specifies the number of bytes that you want to be transferred. I use 2, because there are two bytes in an integer (the last time I checked). I would really appreciate it if someone sends me a table listing the amount of bytes each data type in VB takes up. EXAMPLE My demo program is finally out of the infirmary. It took about a minute to make, and 1hour, 59 minutes to debug. All it does is prompt you for a number, then it uses CopyMemory to copy the value to another variable using variable pointers. Check it out! It is quite simple, and I know it isn't the best example around. I was originally going to make a sorting program, but it proved too difficult to debug. So this is what I used instead. The first step I took was create the project structure, which consists of a project (duh), a form, and a module. The code module contains the Win32 API call to CopyMemory. The form consists of a few labels; I won't cover them here because you can check the code. I'll then dissect the code for the form one block at a time. Private Sub cmdTest_Click() Please don't tell me you don't know what this does! Dim Num As Integer   'Source Variable 
    Dim NewNum As Integer 'Target variable 
    Dim SML As Long   'Source Memory Location 
    Dim TML As Long   'Target Memory Location I declared the variables. We're nearing the meat of the program! 'Error Handling 
    If Not IsNumeric(txtVal.Text) Then 
      MsgBox "X not numeric!" 
      Exit Sub 
    End If 
    If Val(txtVal.Text) > 32767 Then 
      MsgBox "X must be less than 32767!" 
      Exit Sub 
    End If 
    If Val(txtVal.Text) < -32768 Then 
      MsgBox "X must be greater than -32768!" 
      Exit Sub 
    End If 'Assign values 
    Num = Val(txtVal.Text) 
    NewNum = 0 
           以上代码来自: SourceCode Explorer(源代码数据库)
               复制时间: 02-6-4 18:06:25
               当前版本: 1.0.682
                   作者: Shawls
               个人主页: Http://Shawls.Yeah.Net
                 E-Mail: [email protected]
                     QQ: 9181729
      

  6.   

    VB中使用指针下The preceding was some error checking, to ensure that X is within the boundaries of an integer, and then after that, I assigned X to that value. 'Get Memory Locations 
    SML = VarPtr(Num) 
    TML = VarPtr(NewNum) 
       
    'CopyMemory 
    CopyMemory NewNum, ByVal SML, 2 'Or CopyMemory NewNum, Num, 2 This code is the heart of the program. It simply assigns SML and TML the memory locatiosn of Num and NewNum. Then, it uses CopyMemory to copy data from Num to NewNum. I could have used the code inside the comments, but I wanted to demonstrate what you could do with variable pointers. 'Display Results 
    lblMemLoc.Caption = "Source Memory Location: " & Str(SML) 
    lblNewMemLoc.Caption = "Target Memory Location: " & Str(TML) 
    lblNewVal.Caption = "Value of target after CopyMemory: " & Str(NewNum) After all that, I simply displayed the results. And that's that! CONCLUSION Pointers used to belong only in the C++ realm. But with the discovery of VarPtr, and the use of CopyMemory, Visual Basic now has this feature. I hope I have documented this feature well. But pointers can be hard to manage, if you're not careful. So harness this power well... Good luck! ====================================== Tom Quantum 
    Please leave comments! I appreciate any kind of feedback. And if you find this useful, I would appreciate it if you vote for it. That way, I will make better articles in the future.       以上代码来自: SourceCode Explorer(源代码数据库)
               复制时间: 02-6-4 18:06:35
               当前版本: 1.0.682
                   作者: Shawls
               个人主页: Http://Shawls.Yeah.Net
                 E-Mail: [email protected]
                     QQ: 9181729
      

  7.   

    Thanks  very much
    ^_^