FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Harbour method address
Posts: 116
Joined: Thu Oct 13, 2005 05:14 PM
Harbour method address
Posted: Fri May 27, 2011 08:29 PM

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

Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Harbour method address
Posted: Sun May 29, 2011 10:52 AM
Roberto,

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

Code (fw): Select all Collapse
#include "hbclass.ch"

function Main()

   MsgInfo( ValType( @Test_One() ) )

return nil

CLASS Test

   METHOD One

ENDCLASS

METHOD One CLASS Test

return nil
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 116
Joined: Thu Oct 13, 2005 05:14 PM
Re: Harbour method address
Posted: Mon May 30, 2011 07:12 AM
Thx Antonio but I need to access from outside the PRG.

In xHarbour I wrote this, and it works:
Code (fw): Select all Collapse
#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 (fw): Select all Collapse
    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
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Harbour method address
Posted: Mon May 30, 2011 07:29 AM

Roberto,

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

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 116
Joined: Thu Oct 13, 2005 05:14 PM
Re: Harbour method address
Posted: Mon May 30, 2011 07:36 AM

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

Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Harbour method address
Posted: Mon May 30, 2011 07:45 AM

Roberto,

You may use:

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

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Harbour method address
Posted: Mon May 30, 2011 07:49 AM

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

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 116
Joined: Thu Oct 13, 2005 05:14 PM
Re: Harbour method address
Posted: Mon May 30, 2011 08:00 AM

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

Continue the discussion