有一个字符串变量,其内容为某函数/过程名,请问怎样实现根据变量的内容去调用相应的函数/过程?(50分)

  • 主题发起人 主题发起人 tanxh
  • 开始时间 开始时间
T

tanxh

Unregistered / Unconfirmed
GUEST, unregistred user!
请教各位大虾:有一个字符串变量,其值取自数据库,内容为
某函数/过程名,请问怎样实现根据变量的内容去调用相应的函数/过程?
 
先要根据这个名字找到改过程的地址。然后访问该地址。
 
函数如果是自己写的,就直接调用啊。
如果是在另一个DLL里面,那就要费一番心思了。
参考帮助文件或参考书中的“动态调用DLL”。比较繁琐。
 
不知是不是我理解错了,我觉得很容易啊,判断变量内容,调用函数就是了,最简单的方法把所有用到的都罗列出来就是了,如果你是想像在foxpro这种语言种那样把变量内容当语句执行的话,我就搞不清了,你可以看看是不是有类似于什么exec()之类的函数可以把变量作参数,当过程执行。
 
1 Case FunctionName of
name1: 调函数
name2: ……
…………
end;

2 用Com
 
To vbxu
----->如果你是想像在foxpro这种语言种那样把变量内容当语句执行
----->你可以看看是不是有类似于什么exec()之类的函数可以把变量作参数,当过程执行。

正是受foxpro的影响,不知道Windows 或 Delphi中是否有类似的宏替换之类的
函数没有???我不想用罗列的方法,请各位大虾帮忙想想有什么好办法没有。



 
习习,没这么复杂,用MethodAddress这个函数就可以了. :-)
 
To cAkk:
用MethodAddress函数可得到函数入口地址,但是参数值传不进去,请问会是
什么原因?我的测试程序如下:

unit test1;
interface
type
TTestAddr = Class(TObject)
published
function AddIt(ii : integer):integer;
end;
implementation

function TTestAddr.Addit(ii:integer):integer;
begin
result := ii + 1;
end;

end.


unit test2;
interface
type
mf = function(ii:integer):integer;
form1 = Class(TForm)
Button1 : TButton;
procedure Button1Click(sender : TObject);
end;
implementation
uses test1;
{$R *.dfm}
procedure Button1Click(sender : tobject);
var pp : pointer;
ff : mf;
tt : TTestAddr;
nn : integer;
begin
tt := TTestAddr.Create;
pp = tt.MethodAddress('AddIt');
if pp = nil then
button1.caption := 'hello error'
else
begin
ff := mf(pp);
nn := ff(12)
{结果nn不等于13,什么地方有错呢?
跟踪进AddIt,发现传进去的参数值不是12了}
button1.caption := 'hello'+inttostr(ii);
end;
tt.free;
end;
end.

TObject类,利用RTTI,可实现根据函数名字获得其入口地址.
那么,一般的全局函数是否有办法根据名字获得其入口地址?

请cAkk及各位高手多帮助.谢谢!!!



 
可以把你的全局函数写到dll里,然后用
loadlibrary 和 getprocaddress来调用函数

methodaddress肯定也是可以用的。
 
首先,谢谢各位帮忙。
To hubdog:
请问用Package与DLL有何区别?在delphi环境中,哪个好些?
用methodaddress获得函数地址后,如何才能使正确传递参数?

To cAkk:请再指点一二。
 
强制类型转换
var
str1 : pchar;
...
str1 := (PChar)str;

WinExec(str1,...)
就可以了!

因为需要一个最后带#0的子串才可以用!
 
请大家多帮忙,我真着急呀!
 
1)你的类型定义有错,
mf的定义应该为:
mf : function (I : Integer) : Integer of object;
因为它是一个对象方法,所以你不能将它赋给一个普通的指针,按你原来的调用方式,传入的值应该是tt的地址,即Self对象的地址。
可以这样来声明mf:
mf = function (AObj : TObject
AInt : Integer) : Integer;
在调用的时候对第一个参数传NIL即可




2)一般的全局函数不能根据名字获得其入口地址,除非你自己用一个数据结构保存它。

 
我的测试程序片段如下:

TAddIt = Class(TObject)
published
function AddIt(AInt : Integer) : Integer;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function TAddIt.AddIt(AInt : Integer) : Integer;
begin
Result := AInt + 1;
end;

type
TAddMethod = function (AObj : TObject
AInt : Integer) : Integer;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
AddItObj : TAddIt;
AddItAddr : Pointer;
AddMethod : TAddMethod;
R : Integer;
begin
AddItObj := TAddIt.Create;
AddItAddr := AddItObj.MethodAddress('AddIt');
AddMethod := TAddMethod(AddItAddr);
R := AddMethod(nil, 3);
ShowMessage(IntToStr(R));
AddItObj.Free;
end;

 
多人接受答案了
 
后退
顶部