不行啊, 假定你的这个办法写了一个涵数: 'Obj传入对像 'strSubName 准备要取得的涵数指针 function GetObjectFuncPtr(obj as Object ,strSubName as string )as long 这时候调用者只有一个己实例好的对象,和己知的过程名,对象的实现代码不是他写的,那他没有办法取得指针了 你的方法只能取得自己写死的类对像中的涵数指针,不能按过程名取得别人写好的类中的涵数指针
不是BT,偶的想法是,一个可以为了在类里面实现AddressOf ,另一个是为了Hook COM我查了一下GetIDsOfNames()的用法,结果指针取不到,倒是误打误撞,搞到了个CallByName()的实现方法 '=====================类 : Class1=========== Public Function ABCDEFG() MsgBox "OK" End Function '==========================================='******************************************* Option Explicit Private Const IID_NULL As String = "{00000000-0000-0000-0000-000000000000}" Private Declare Function GetUserDefaultLCID Lib "kernel32" () As LongPrivate Sub Command1_Click() Dim obj As Class1
Dim IDispatch As olelib.IDispatch Dim DISPID As Long Dim IID_NULL_UUID As UUID
Dim tmp As Long Dim praram As olelib.DISPPARAMS Dim exc As olelib.EXCEPINFO Dim ivk As INVOKEKIND Dim ti As ITypeInfo
下面这应该是你想要的
http://www.cnblogs.com/pctgl/articles/1586841.html
Modest你用什么方法子类化?教教大家
http://www.cnblogs.com/pctgl/articles/1352916.html加强版本的文章
http://www.cnblogs.com/pctgl/articles/1566676.html
早期文章中,有关默认参数的问题,其实是 function 函数过程的返回值,sub 函数的返回值由于没有,所以不设计到以参数代替返回值的方式。
你要通用的也可以 通用中声明一个数组: dim linkproc() as longPrivate Function GetClassProcAddress(ByVal SinceCount As Long, ByVal ParamsCount As Long) As Long
Dim mePtr As Long
Dim jmpAddress As Long
mePtr = ObjPtr(Me)
CopyMemory jmpAddress, ByVal mePtr, 4
CopyMemory jmpAddress, ByVal jmpAddress + (SinceCount - 1) * 4 + &H1C, 4
ReDim LinkProc(8)
LinkProc(0) = &H83EC8B55: LinkProc(1) = &HFC8BFFEC: LinkProc(2) = &H3308758D: LinkProc(3) = &HFCFFB1C9
LinkProc(4) = &HFF68A5F3: LinkProc(5) = &HB8FFFFFF: LinkProc(6) = &HFFFFFFFF: LinkProc(7) = &HC2C9D0FF: LinkProc(8) = &HFF
CopyMemory ByVal VarPtr(LinkProc(1)) + 1, ParamsCount * 4, 1
CopyMemory ByVal VarPtr(LinkProc(3)) + 2, ParamsCount, 1
CopyMemory ByVal VarPtr(LinkProc(4)) + 3, mePtr, 4
CopyMemory ByVal VarPtr(LinkProc(6)), jmpAddress, 4
If ParamsCount = 0 Then CopyMemory ByVal (VarPtr(LinkProc(7)) + 3), &HC3, 1
LinkProc(8) = ParamsCount * 4
GetClassProcAddress = VarPtr(LinkProc(0))
End Function使用方法:
类模块内的函数地址 = GetClassProcAddress (从最上面数,第N个公用函数,或者所有公用函数个数 + 第 N 个私有函数, 该函数的参数个数)属性也算公用函数,数一下就行了,需要点使用技巧,这个东西还不是十分完善,都是早期临时写的,到后期也没什么兴趣完善他了,只不过后来补充了一个 GetWndProcAddress 用来实现子类化GetClassProcAddress 获取的不是真正的函数地址,是一个用汇编构造的小函数地址,由这个函数转发调用真正的函数的过程, 真正的函数地址:
CopyMemory jmpAddress, ByVal jmpAddress + (SinceCount - 1) * 4 + &H1C, 4
这句就得到了,不过不能直接调用,因为这不是普通的标准模块中的函数,所以
虽然不是通过按名字取id然后获取函数地址的方式实现的
但这个过程可能是最简单的方法说太多了 lz 觉得没用就算了吧
pctgl的代码已经很不错了
我嘛,早先有个舶来品,不知道能否找得到。在公司电脑里,等明天吧...
特别是第十一章。
不行啊,
假定你的这个办法写了一个涵数: 'Obj传入对像
'strSubName 准备要取得的涵数指针
function GetObjectFuncPtr(obj as Object ,strSubName as string )as long
这时候调用者只有一个己实例好的对象,和己知的过程名,对象的实现代码不是他写的,那他没有办法取得指针了
你的方法只能取得自己写死的类对像中的涵数指针,不能按过程名取得别人写好的类中的涵数指针
1个限制,必须是 VB 的对象,而且是基类对象
如果是对窗口对象,控件对象直接这样做将会出现错误,除非首先找到真正的基类对象句柄再说如果在以上的限制之内,那么完全可以的,这个函数的原理其实就是用汇编写了一个类中的
函数调用的小函数,外部调用这个函数时就象标准函数一样,比如和标准模块中的函数一样再简单点说就是在标准模块中写了一个函数,然后在这个函数中调用了类中的函数,模块中的函数
地址你有了,你可以直接给 callback之类的api使用vb编译对象中的函数,属性,一般情况下的规则就是自代码顶端,先公用,再私用的方法依次编译
实际上,这个依次就是 ID ,所以你要明确的知道函数在类中的顺序,然后调用这个方法,他才能正确的
解析到正确的函数,才能正确的调用lz的要求太bt了
'=====================类 : Class1===========
Public Function ABCDEFG()
MsgBox "OK"
End Function
'==========================================='*******************************************
Option Explicit
Private Const IID_NULL As String = "{00000000-0000-0000-0000-000000000000}"
Private Declare Function GetUserDefaultLCID Lib "kernel32" () As LongPrivate Sub Command1_Click()
Dim obj As Class1
Dim IDispatch As olelib.IDispatch
Dim DISPID As Long
Dim IID_NULL_UUID As UUID
Dim tmp As Long
Dim praram As olelib.DISPPARAMS
Dim exc As olelib.EXCEPINFO
Dim ivk As INVOKEKIND
Dim ti As ITypeInfo
Set obj = New Class1
Set IDispatch = obj
tmp = VarPtr(DISPID)
Call olelib.CLSIDFromString(IID_NULL, IID_NULL_UUID)
'这两句,可以实现CallByName()
Call IDispatch.GetIDsOfNames(IID_NULL_UUID, "ABCDEFG", 1, GetUserDefaultLCID(), tmp)
IDispatch.Invoke tmp, IID_NULL_UUID, GetUserDefaultLCID, DISPATCH_METHOD, praram, DISPID, exc, tmp Debug.Print IDispatch.GetTypeInfo(0, GetUserDefaultLCID()).AddressOfMember(tmp, INVOKE_FUNC)
' tmp = Poke(DISPID) obj.ABCDEFG
Set IDispatch = Nothing
Set obj = Nothing
End Sub
'*******************************************
这个涵数有点似呼有点看头,可惜我GOOGLE不到详细的说明