Skip to Content
0
Sep 17, 2014 at 02:37 PM

ABAP OO/RTTI: dynamic method invocation and type determination

598 Views

Hi,

I tinker with the possibilities of dynamic method invocation in ABAP objects and have run into the following issue:

Using the class CL_ABAP_CLASSDESCR I can determine the methods provided by a certain class and the methods' parameters. The method descriptions use the table line structure


begin of abap_parmdescr,
length type i,
decimals type i,
type_kind type abap_typekind,
name type abap_parmname,
parm_kind type abap_parmkind,
by_value type abap_bool,
is_optional type abap_bool,
end of abap_parmdescr,


for describing parameters. When I know that a certain parameter has type REF TO <some class X> I don't see how I can retrieve the concrete class (that is: which class is <some class X>?). The parameter description seems to only say "the parameter is a reference", but it doesn't tell a reference to which class/data type is expected.


To give a code example of the issue: I declared a helper class ZCL_VH_OBJECT_MAP:


class ZCL_VH_OBJECT_MAP definition public final create public .

public section.

class-methods CREATE_MAP
importing
value(IV_NUM_DEFAULT_ENTRIES) type I default 3
value(IR_COPY_CONTENT_FROM) type ref to CL_OBJECT_MAP optional
returning
value(RR_MAP) type ref to CL_OBJECT_MAP .


ENDCLASS.

CLASS ZCL_VH_OBJECT_MAP IMPLEMENTATION.
METHOD create_map.
DATA lr_null TYPE REF TO object.

IF ir_copy_content_from IS NOT BOUND.
rr_map = NEW #( ).
ELSE.
rr_map = NEW #( ir_copy_content_from->map ).
ENDIF.

DO iv_num_default_entries TIMES.
rr_map->put(
EXPORTING
key = sy-index
value = lr_null ).
ENDDO.
ENDMETHOD.
ENDCLASS.



Now I try to invoke the method CREATE_MAP dynamically like this:


REPORT zvh_di_2.

DATA: gr_object TYPE REF TO object,
gr_map TYPE REF TO cl_object_map,
gr_my_map TYPE REF TO cl_object_map,
gt_param_tab TYPE abap_parmbind_tab,
gs_param TYPE abap_parmbind,
gv_class_name TYPE string,
gv_method_name TYPE string,
gr_classdescr TYPE REF TO cl_abap_classdescr.


START-OF-SELECTION.

BREAK-POINT.

gv_class_name = `ZCL_VH_OBJECT_MAP`.
gv_method_name = `CREATE_MAP`.


gr_map = NEW #( ).
gr_object = gr_map. " up cast

gr_classdescr ?= cl_abap_classdescr=>describe_by_name( gv_class_name ).

" GR_CLASSDESCR->METHODS[1]-PARAMETERS contains the parameter description
" for the single method I'd like to invoke dynamically below.
" I can determine that for the parameter IR_COPY_CONTENT_FROM I have to
" supply a reference.
" But a REF TO which concrete class? Passing a REF TO OBJECT doesn't work, see below!

gs_param-name = 'IR_COPY_CONTENT_FROM'.
gs_param-kind = cl_abap_objectdescr=>exporting.

* GET REFERENCE OF gr_object INTO gs_param-value. " dumps
GET REFERENCE OF gr_map INTO gs_param-value. " works

INSERT gs_param INTO TABLE gt_param_tab.

gs_param-name = 'RR_MAP'.
gs_param-kind = cl_abap_objectdescr=>receiving.
GET REFERENCE OF gr_my_map INTO gs_param-value.
INSERT gs_param INTO TABLE gt_param_tab.

CALL METHOD (gv_class_name)=>(gv_method_name) PARAMETER-TABLE gt_param_tab.


How can I determine in the code which kind of reference I have to supply in the dynamic method invocation?