Page 1 of 1

Harbour method address

Posted: Fri May 27, 2011 8:29 pm
by Roberto Parisi
How to get address of a class method?

I wonder a way like getting function address (@MyFunc()):

@TMyClass:MyMethod()

Is this possible?

Thx,
Roberto Parisi

Re: Harbour method address

Posted: Sun May 29, 2011 10:52 am
by Antonio Linares
Roberto,

This works if your code is inside the same Class PRG:

Code: Select all

#include "hbclass.ch"

function Main()

   MsgInfo( ValType( @Test_One() ) )

return nil

CLASS Test

   METHOD One

ENDCLASS

METHOD One CLASS Test

return nil

Re: Harbour method address

Posted: Mon May 30, 2011 7:12 am
by Roberto Parisi
Thx Antonio but I need to access from outside the PRG.

In xHarbour I wrote this, and it works:

Code: Select all

#include "hbapi.h"
#include "hboo.ch"
#include "classes.h"
    
HB_FUNC(__GETMETHODPOINTER) {
    PMETHOD pMethod = hb_objGetpMthd(hb_dynsymGet(hb_parc(2)), hb_parnl(1));
    if (pMethod && pMethod->uiType == HB_OO_MSG_METHOD) hb_retptr(pMethod->pFunction);
}
 
In Harbour I don't have any (or similar) hb_objGetMethodPointer function globally defined.

I wrote this and It works but due to the static function hb_clsFindMsg I need to insert the code inside classes.c. I don't like it.

Code: Select all

    HB_FUNC( __GETMETHODPOINTER )
    {
       USHORT uiClass = ( USHORT ) hb_parni( 1 );
       PHB_ITEM pString = hb_param( 2, HB_IT_STRING );
    
       if( uiClass && uiClass <= s_uiClasses && pString &&
           ! s_pClasses[ uiClass ]->fLocked )
       {
          PHB_DYNS pMsg = hb_dynsymFindName( pString->item.asString.value );
          
          if( pMsg )
          {
             PCLASS  pClass  = s_pClasses[ uiClass ];
             PMETHOD pMethod = hb_clsFindMsg( pClass, pMsg );
    
             if( pMethod )
             {
        if (pMethod->itemType == HB_OO_MSG_METHOD) { 
          if (pMethod->pFuncSym->value.pFunPtr) {
            hb_itemPutSymbol( hb_stackReturnItem(), pMethod->pFuncSym );
        }
               }
             }
          }
       }
    }
 
Do you have any suggest?

Thx,
Roberto Parisi

Re: Harbour method address

Posted: Mon May 30, 2011 7:29 am
by Antonio Linares
Roberto,

What do you need it for ? Just curiosity... :-)

Re: Harbour method address

Posted: Mon May 30, 2011 7:36 am
by Roberto Parisi
I need to split and / or redefine methods over multiple files (usig our __GetPointer with CLSMODMSG). This is great for our software client custumization. It works fine in xHarbour but now we are porting it in Harbour.

Regards,
Roberto Parisi

Re: Harbour method address

Posted: Mon May 30, 2011 7:45 am
by Antonio Linares
Roberto,

You may use:

OVERRIDE METHOD <MethodName> IN CLASS <ClassName> WITH <YourMethodName>

Re: Harbour method address

Posted: Mon May 30, 2011 7:49 am
by Antonio Linares
Roberto,

My mistake, that is only available for xHarbour. But I guess you may use __clsModMsg() in Harbour:

__clsModMsg( hClassH, cSymbol, bCode or pCode )

It is inside classes.c

Re: Harbour method address

Posted: Mon May 30, 2011 8:00 am
by Roberto Parisi
I know it.
I need to redefine the method and AFTER call the original method. It is like to split the method over two files.

// File1.prg
Method Test() class TCustomClass
MsgAlert("I'm in File1.prg")
return nil

// File2.prg
Method Test() class TCustomClass
MsgAlert("I'm in File2.prg")
return original()

Calling File2.prg -> Test I get two alerts:
I'm in File2.prg
I'm in File1.prg

original is an #xcommad to call the pointer of Test() in File1.prg. I can do it with class Inheritance but base class has to be the same and not different.
I call it "slice methods" :)

Regards,
Roberto Parisi