type
TaClass = class
public
procedure AProc;
end;var
PtrOfAProcAddr : Pointer;求将AProc的地址赋给PtrOfAProcAddr
TaClass = class
public
procedure AProc;
end;var
PtrOfAProcAddr : Pointer;求将AProc的地址赋给PtrOfAProcAddr
解决方案 »
- 关掉了{$Q}还有溢出的错误
- Delphi中sockets通信编程如何绕过防火墙??
- 动态彩色菜单(带图标)制作的问题?
- 关于dbgrideh的问题
- 誰有fastreport3.0的教材
- 事务可否单独写成独立的函数?不知道这样写是否稳妥。
- 关于屏幕取词技术的Delphi源代码,谁要呀,就快来呀!!
- 有没有分组的ListView控件,或者说怎么可以实现?
- 请问我把一个内容,同时发送到三台不同的打印机应该怎么做。。。急。。万分感谢!
- DLL 有些不懂?请问如何返回加载成功和失败?
- ADOTable控件连接数据库,使用DBGRID控件,当记录移动到最后一个,再向下移动就出错??
- 哪位有“Midas.idl”的文件,或告诉能从哪里下载
如果要通过PtrOfProcAddr调用AProc,
最好定义类型TAProc = proc of object;...
public
procedure AProc;
constructor Create;
end;constructor TaClass.Create;
begin
inherited Create;
PtrOfAProcAddr := @AProc;
end;...
而且一般来说不是定义成PtrOfAProcAddr: Pointer
是这样:
type
TProcEvent = procedure of object;var
PtrofAProcAdd: TProcEvent;那么这样,PtrOfAProcAddr和AProc就遥相呼应了。
TNotifyEvent = procedure (Sender: TObject) of object;如是C/C++的话,只是:
typedef void (*NOTIFYEVENT)();
而CB中对应加了(__closure)参数,和标准C不同,和VC也不同。
typedef void __fastcall (__closure *TNotifyEvent)(TObject* Sender);Pointer是可以转成对procedure of object之类的类型指针,不同有点麻烦,所以一般来说VCL很多的全局方法/函数指针都有明确的类型,而不是Pointer,底层一点就是用Pointer,但所对应的就不是类里面的方法,而是具体的:
procedure Proc;
function Func: Pointer;
ta: Taclass;
PtrOfAProcAddr : Pointer;begin
ta:= Taclass.Create;
PtrOfAProcAddr:= ta.MethodAddress('Aproc');
ShowMessage(format('%d', [integer(@PtrOfAProcAddr)]));
ta.Free;
end;
var
PtrOfAProcAddr : Pointer;
时PtrOfAProcAddr := @AProc;
不能通过编译。当声明为
type
TClassProcedure = procedure of object;var
PtrOfAProcAddr : TClassProcedure;
可以
PtrOfAProcAddr := AProc;不过得到的是TMethod纪录,要得到它的地址,还需要进一步操作。var
ClassProc: TClassProcedure;
P: ^TMethod;
PtrOfAProcAddr: Pointer;
begin
ClassProc := AProc;
P := @ClassProc;
PtrOfAProcAddr := P^.Code;
end;
不过我的主要目的不是这个。我要做一个这样的函数:
function GetClassMethodAddr(var aMethod: TClassProcedure): Pointer;
var
MethodPtr: ^TMethod;
begin
MethodPtr := @aMethod;
Result := MethodPtr^.Code;
end;但,假如要取下面的B函数的地址:type
TaClass = class
function BProc: Integer;
end; type
TClassFunction = function of object;就必须再写一个这样的函数,
function GetClassMethodAddr(var aMethod: TClassFunction): Pointer;如果参数不同,还需要为每一个声明写一个函数。有没有办法只需一个声明,就可以让aMethod满足所有的类过程或函数的参数。
不知道说清楚了没有
PtrOfAProcAddr :=MakeObjectInstance(TaClass.MethodName)
ok
To copy_paste(木石三):
我修改public成published,得出得结果一样,怎解?
谢谢!!!
我是想得到函数的地址,不是再建造一个函数。不过还是谢谢你的参与。再一次谢谢。
也谢谢大家
只对published的property和event有效。
TAClass = class
published
procedure AProc; //published关键字不可少
public
function BProc: Integer;
constructor Create;
end;procedure TForm1.Button1Click(Sender: TObject);
var
P: pointer;
A: TAClass;
begin
A := TAClass.Create;
P := A.MethodAddress('AProc');
if Assigned(P) then
Caption := Format('%p', [P]);
A.Free;
end;如果想多知道些这么东西,看看这里介绍:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1642063
TAClass = class
private
FAddrA: Pointer;
FAddrB: Pointer;
public
procedure AProc;
function BProc: Integer;
constructor Create;
property AddrA: Pointer read FAddrA;
property AddrB: Pointer read FAddrB;
end; TProcEvent = procedure of object;
TFuncEvent = function: Integer of object;
{ TAClass }procedure TAClass.AProc;
begin
ShowMessage('AProc');
end;function TAClass.BProc: Integer;
begin
Result := 0;
ShowMessage('BProc');
end;function GetMethod(ACode: Pointer; AData: Pointer = nil): Pointer; // result is PMethod
var
Data: ^TMethod;
begin
New(Data);
Result := Data;
Data.Code := ACode;
Data.Data := AData;
end;constructor TAClass.Create;
var
Proc: TProcEvent;
Func: TFuncEvent;
begin
inherited Create;
Proc := AProc;
FAddrA := Some(@Proc); Func := BProc;
FAddrB := Some(@Func);
end;procedure TForm1.Button1Click(Sender: TObject);
var
P: ^TMethod;
Proc: TProcEvent;
Func: TFuncEvent;
A: TAClass;
begin
A := TAClass.Create;
P := A.AddrA;
TMethod(Proc).Code := P^.Code;
TMethod(Proc).Data := P^.Data;
Proc(); P := A.AddrB;
TMethod(Func).Code := P^.Code;
TMethod(Func).Data := P^.Data;
Caption := IntToStr(Func());
A.Free;
end;
constructor TAClass.Create;
var
Proc: TProcEvent;
Func: TFuncEvent;
begin
inherited Create;
Proc := AProc;
FAddrA := GetMethod(@Proc); Func := BProc;
FAddrB := GetMethod(@Func);
end;
你的程序是可以正常运行,但是也只是在TaClass的函数体内执行。如果再在下面这个函数体内执行aMethod,你怎么办呢?procedure CallMethod(aObject: TaClass; aMethod: TProcEvent);
beginend;你最终还是要转换成我的那种办法。而且你的办法也不能逃脱用TProcEvent来避开
编译器的语法检查。好像是没有办法直接得到函数的地址。像@操作符那样。
var
ThreadID: DWORD;
P: function(P: Pointer): DWORD of object;
begin
P := ThreadFunc;
CloseHandle(Createthread(nil, 0, @P, nil, 0, ThreadID));
end;function TForm1.ThreadFunc(Param: Pointer): DWORD;
var
P2: function(P: Pointer): DWORD of object;
begin
P2 := ThreadFunc;
Result := 0;
MessageBox(0, 'Thread Hello', 'ok', MB_OK);
end;
type
TaClass = class
public
procedure AProc;
end;var
PtrOfAProcAddr : Pointer;proceudre test
begin
PtrOfAProcAddr := @TaClass.AProc;
end;
告诉我,Delphi帮助文件中的主题是什么?
你的办法还真的行啊,爽啊,今天晚上喝酒喝的爽啊,爽啊我本来是着这样想的
PtrOfAProcAddr := @(TaClass.AProc);
不行,就没再试了,但怎么没有试试@TaClass.AProc,哎,无所谓,放分嘛,
爽ingcopy_paste大佬,辛苦了,
同志们,辛苦啦
鸣谢(字母序):
========================
copy_paste大佬
ehom大佬
fancier大佬
Kingron大佬
NightCloud大佬
nobition大佬
qiume大佬
selly大佬
SGP大佬
xiaocha大佬
为了答谢SGP大佬的正确答案,以另开一帖请您接分,请移步:
http://expert.csdn.net/Expert/topic/1481/1481646.xml?temp=.1861536
type
TMyClass = class
private
FValue: Integer;
public
procedure B;
end;procedure TMyClass.B;
begin
FValue := 10;
end;procedure TForm1.FormCreate(Sender: TObject);
var
P: Pointer;
begin
P := @TFormDD.B;
TProcedure(P)();
end;不要告诉我,你专门写了个类,全是静态的方法/函数