public class ImplIfc extends SimpleClass implements Ifc, Ifc2
SimpleDataStruct
is a very simple class, only contains data.
The interfaces are complex, it contains methods with same name but different parameters,
also dispersed to both interfaces. So the implementation of methods using method tables
can be demonstrated. See descriptions of the method.
typedef struct ImplIfc_Test_t { union { ObjectJc object; ExpandableDataStruct_Test_s super; Ifc_Test_s Ifc_Test;Ifc2_Test_s Ifc2_Test; } base; int32 val; } ImplIfc_Test_s;The other struct is the method table, it is shown as explanation on method
anotherIfcmethod(float)
.
The method table shows and represents the structure of dynamic call-able (virtual) methods
including the inheritance- and interface structure of this class. The implementation of interface
of this class in Java is transformed in C in the first place there.constString, constValue, constValue2
Modifier and Type | Method and Description |
---|---|
float |
anotherIfcmethod(float input)
This methods implements both methods declared in Interface
Ifc.anotherIfcmethod(float)
and Ifc2.anotherIfcmethod(float) . |
int |
anotherIfcmethod(int input)
This method is declared in the interface
Ifc.processIfcMethod(int) . |
float |
processIfcMethod(float input)
Example for a method which is final but implements an interface method (the same is if it
overrides methods from a super class).This method implements
Ifc.processIfcMethod(int) . |
int |
processIfcMethod(int input)
Example for a method which is override-able and implements an interface method.
|
float |
testIfc2(float input)
This method implements
Ifc2.testIfc2(float) . |
java.lang.String |
toString() |
public int processIfcMethod(int input)
Ifc.processIfcMethod(int)
.
The method is declared in C as
METHOD_C int32 processIfcMethod_i_ImplIfc_Test_F(ObjectJc* ithis, int32 input, ThCxt* _thCxt);The middle part of name is
_i_
because there is also a variant of the method
with another parameter types. The suffix _F
is because the implementation version
of the method is the final version, but the user may call the also declared method:
METHOD_C int32 processIfcMethod_i_ImplIfc_Test(ObjectJc* ithis, int32 input, ThCxt* _thCxt);This variant implements the dynamic call (virtual method) internally.
int32 processIfcMethod_i_ImplIfc_Test_F(ObjectJc* ithis, int32 input, ThCxt* _thCxt) { ImplIfc_Test_s* ythis = (ImplIfc_Test_s*)ithis; STACKTRC_TENTRY("processIfcMethod_i_ImplIfc_Test_F"); { { STACKTRC_LEAVE; return ythis->base.super.xb + input + ythis->val; } } STACKTRC_LEAVE; }The this-pointer is given in Form of ObjectJc, because it is an implementation of an interface method. The cast to the real type is done in the next line. It is a unchecked cast. It may be correct, because this method is only called
instanceof Type
in Java. Another possibility were,
to generate a type test depending on @ java2c=checkType - annotation. This is not implemented yet,
but it was a possible feature for methods, which overrides or implements base methods.
/ *J2C: dynamic call variant of the override-able method: * / int32 processIfcMethod_i_ImplIfc_Test(ObjectJc* ithis, int32 input, ThCxt* _thCxt) { Mtbl_Ifc_Test const* mtbl = (Mtbl_Ifc_Test const*)getMtbl_ObjectJc(ithis, sign_Mtbl_Ifc_Test); return mtbl->processIfcMethod(ithis, input, _thCxt); }If the user doesn't determine that an instance is type of a given instance, a reference may refer an instance with derived type. The method may be overridden there. Therefore the dynamic call should be done. But a normal C user doesn't may know this mechanism, it may be a call of the method from manual written C-code. Therefore the dynamic call is implemented here. Another way is to organize the dynamic call at user level, in the adequate kind as generated here.
processIfcMethod
in interface Ifc
input
- Examplepublic final float processIfcMethod(float input)
Ifc.processIfcMethod(int)
.
The method is declared in C as
METHOD_C float processIfcMethod_f_ImplIfc_Test(ObjectJc* ithis, float input, ThCxt* _thCxt);The middle part of name
_f_
, because another method which the same name exists.
For this method no variant with a suffix _F
exists, because this method is final itself.
No extra final method is necessary.
processIfcMethod(int)
, see there.processIfcMethod
in interface Ifc2
public final int anotherIfcmethod(int input)
Ifc.processIfcMethod(int)
.anotherIfcmethod
in interface Ifc
public java.lang.String toString()
toString
in class java.lang.Object
public final float testIfc2(float input)
Ifc2.testIfc2(float)
. @java2c=override-able.public float anotherIfcmethod(float input)
Ifc.anotherIfcmethod(float)
and Ifc2.anotherIfcmethod(float)
. Only one implementation is necessary in Java
and in the translated C too. The Implementation is defined in the Headerfile:
METHOD_C int32 anotherIfcMethod_f_ImplIfc_Test_F(ImplIfc_Test_s* ythis, int32 input, ThCxt* _thCxt); METHOD_C int32 anotherIfcMethod_f_ImplIfc_Test(ImplIfc_Test_s* ythis, int32 input, ThCxt* _thCxt);The first form is the implementation method. The second form is the method, which realizes the dynamically call because the method is override-able.
typedef struct Mtbl_ImplIfc_Test_t { MtblHeadJc head; MT_testOverrideAble_ImplIfc_Test* testOverrideAble; Mtbl_ExpandableDataStruct_Test ExpandableDataStruct_Test; //Method table of interfaces: Mtbl_Ifc_Test Ifc_Test; Mtbl_Ifc2_Test Ifc2_Test; } Mtbl_ImplIfc_Test;Both interfaces are contained. The definition of the instance of methode table for this class in the C-File
ImplIfc_Test.c
contains the reference to the implementation method
at twice positions:
const struct { Mtbl_ImplIfc_Test mtbl; MtblHeadJc end; } mtblImplIfc_Test = { { { sign_Mtbl_ImplIfc_Test//J2C: Head of methodtable. , (struct Size_Mtbl_t*)((2 +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types. } , anotherIfcMethod_ImplIfc_Test_F //anotherIfcMethod , testOverrideAble_ImplIfc_Test_F //testOverrideAble , { { sign_Mtbl_ExpandableDataStruct_Test//J2C: Head of methodtable. , (struct Size_Mtbl_t*)((0 +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types. } , { { sign_Mtbl_ObjectJc//J2C: Head of methodtable. , (struct Size_Mtbl_t*)((5 +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types. } , clone_ObjectJc_F //clone , equals_ObjectJc_F //equals , finalize_ObjectJc_F //finalize , hashCode_ObjectJc_F //hashCode , toString_ImplIfc_Test //toString } } , { { sign_Mtbl_Ifc_Test//J2C: Head of methodtable. , (struct Size_Mtbl_t*)((3 +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types. } , processIfcMethod_i_ImplIfc_Test_F //processIfcMethod , anotherIfcmethod_i_ImplIfc_Test //anotherIfcmethod_i , { { sign_Mtbl_ObjectJc//J2C: Head of methodtable. , (struct Size_Mtbl_t*)((5 +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types. } , clone_ObjectJc_F //clone , equals_ObjectJc_F //equals , finalize_ObjectJc_F //finalize , hashCode_ObjectJc_F //hashCode , toString_ImplIfc_Test //toString } } , { { sign_Mtbl_Ifc2_Test//J2C: Head of methodtable. , (struct Size_Mtbl_t*)((3 +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types. } , processIfcMethod_f_ImplIfc_Test_F //processIfcMethod , testIfc2_f_ImplIfc_Test_F //testIfc2 , anotherIfcmethod_f_ImplIfc_Test_F //anotherIfcmethod , { { sign_Mtbl_ObjectJc//J2C: Head of methodtable. , (struct Size_Mtbl_t*)((5 +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types. } , clone_ObjectJc_F //clone , equals_ObjectJc_F //equals , finalize_ObjectJc_F //finalize , hashCode_ObjectJc_F //hashCode , toString_ImplIfc_Test //toString } } }, { signEnd_Mtbl_ObjectJc, null } }; //MtblThe reference to
anotherIfcmethod_i_ImplIfc_Test
is accordingly to anotherIfcmethod(int)
.anotherIfcmethod
in interface Ifc
anotherIfcmethod
in interface Ifc2