Harbour method address

Post Reply
Roberto Parisi
Posts: 116
Joined: Thu Oct 13, 2005 5:14 pm
Location: Italy

Harbour method address

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Harbour method address

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Roberto Parisi
Posts: 116
Joined: Thu Oct 13, 2005 5:14 pm
Location: Italy

Re: Harbour method address

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Harbour method address

Post by Antonio Linares »

Roberto,

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

Antonio Linares
www.fivetechsoft.com
Roberto Parisi
Posts: 116
Joined: Thu Oct 13, 2005 5:14 pm
Location: Italy

Re: Harbour method address

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Harbour method address

Post by Antonio Linares »

Roberto,

You may use:

OVERRIDE METHOD <MethodName> IN CLASS <ClassName> WITH <YourMethodName>
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Harbour method address

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Roberto Parisi
Posts: 116
Joined: Thu Oct 13, 2005 5:14 pm
Location: Italy

Re: Harbour method address

Post 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
Post Reply