StrPtr你看一下这篇文章,一定不会令你失望http://www.csdn.net/develop/read_article.asp?id=12675
解决方案 »
- 自己开发的报表控件,AC Report Ver2.4,请多支持:)
- 在vb.net中,如何提取上一个界面控件中的信息啊....
- 数组控件应用中,这段代码怎样简化
- 请指导一下,一个自定义函数!
- 怎样在loadpicture时把图片的大小调整一下!!!(最先回答对的给2分)
- [高手请进]如何在不知道对方MAC地址和IP地址的情况下得到mac和ip?
- 急,在线等待,帮忙看看这句话有什么错吗?
- vb 下的控件的大小问题?
- 请问Gif在什么控件里面显示才能显示出动画?谢谢
- 请高手来看看,是DCOM与COM组件的问题,贴有源代码,昨天好好的,今天运行就是自动化错误!没有改源代码!,请看,不知错在何处,为什么发生!
- 关于托盘程序的问题???
- 每人在意的小问题!关于ACESS2000
本文原文: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对象接口定义里的函数定义
varptr 返回变体型变量的地址
strptr 返回字符型变量的址址
VarPtrArray 返回数组变量的址址
VarPtrStringArray 返回字符数组变量的址址
用于获取变量地址,是函数
AddressOf,通常只用于回调,是运算符
作为参数,如果你用的是地址,那么通过byval可以得到地址本身;通过byfef得到的是地址的地址
一个画线工具的程序
使用了链表方式存储端点数据
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
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
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
^_^