trodgers@nmsu.edu (Thomas Rodgers) (12/11/90)
In Reference to : TP5.5: Can't store method in procedure variable I am pleased to find that I am not the only one with this problem! I am constructing an object to encapsulate TurboPower software's BTREE FILER v5.05 calls. It was my desire to have the index definition and key functions as virtual methods that could be overidden in another definition. The relevent go something like : type idx_key_func = function(var dat; key : integer) : IsamKeyStr; idx_def_proc = procedure(var iid: IsamIndDescr)' dbobj = object(root) ... Stuff ... idxkey : idx_key_func; idxdef : idx_def_proc; ... Method Stuff ... procedure SetIdxKeyFunc(ikf : idx_key_func); procedure SetIdxDefProc(idp : idx_def_proc); { So the user doesn't necessarily have to derive a new object to use the database } function IndexKey(var dat; key : integer) :IsamKeyStr;virtual; procedure IndexDef(var iid : IsamIndDescr);virtual; { The Default actions of these are to call the routines in idxkey and idxdef } ... More Stuff ... end; Everything works great, except when my object detects a corrupted database, it calls the standard BTREE rebuild procedure. The chaos and madness starts here. BTREE makes heavy use of procedure pointers, not procedure variables, this is to maintain compatibility with TP4.0, They use inline code inside a local procedure to call the supplied procedure through its pointer. After digging through the OOP guide, I found that virtual methods expect a different stack frame than do ordinary procedures (an invisible self pointer is put on the stack). Needless to say, since the stack frame was not quite the same the call drove off into the weeds. I modified the code of the reorg routines to accept procedure types instead of pointers, and started getting the "Invalid procedure or funtion reference" stuff. It is my opinion that when you declare : type proc = procedure; you are telling the compiler that you want a procedure type of the "standard form" (ie not a method). Since methods have the additional self parameter in their stack frame, they aren't truly the same beasts, the compiler won't let you interchange them. As far as trying to use the @ operator, this doesn't seem to work either (the self parameter still bites us). I have stewed over several possible solutions, but none are very convenient. But if I find one I'll post it.