CRuntimeJavalike - Reflection

CRuntimeJavalike - Reflection

Inhalt


Topic:.ReflectionJc.

.


1 Was bietet das Reflection-Prinzip

Topic:.ReflectionJc.usage.

Last changed: 2007-09-23

Laut Wikipedia bedeutet Reflection: dass ein Programm Erkenntnisse über seine eigene Struktur gewinnen kann. (Stand 23. Sep. 2007). Die Strukturinformationen sind normalerweise in Maschinencodeabläufe, Einzel-Datenadressen und Labels für Subroutinen übersetzt und damit nicht mehr unmittelbar von außen zugänglich. Die Zugänglichkeit besteht nur, wenn diese im Compilierungsprozess berücksichtigt wird. Ein Zugang von außen mit Angabe der Daten oder Subroutinen per Name (Symbol) erfordert ein aufgesetztes zusätzliches System. Solche symbolischen Zugänge sind erforderlich oder interessant

Die Reflection erlauben diesen symbolischen Zugang ohne zusätzliche Informationen wie Mapfiles und Listings und daraus abgeleitete Zugangsdaten.

Die Reflection-Informationen verbinden interne Strukturen mit symbolischer Zugriffsmöglichkeit aus der Quellcode-Ebene. Um diese Informationen gegenüber der unbeabsichtigten Nutzung zu verbergen, sollen textuelle Anteile gegebenenfalls auch chiffriert werden können.


1.1 Reflection in Java

Topic:.ReflectionJc.usage.java.

Last changed: 2013-12-09

Reflection sind in einigen Programmiersprachen wie Java, C#, Python fester Sprachbestandteil und erlauben dort eine flexible Programmierung insbesondere bei Nutzung von Klassen über Netzwerkgrenzen oder dynamischer Programmbestandteile. Die Reflections sind im Java-Standard-Sprachumfang mit den Klassen java.lang.Class und das Package java.lang.reflect repräsentiert. Von jedem Object sind die Reflection-Infos zugänglich. Beim Zugriff wird aber der Zugriffsschutz wie beim Compilieren beachtet. Standardgemäß zugreifbar sind nur public-Elemente. Das entspricht dem objektorientiertem Ansatz. Elemente, die von außen gelesen oder gesetzt werden sollen, müssen public sein. Für einen Zugriff aus rein informatorischen Gründen auf alle Elemente gibt es die Möglichkeit, den private-Zugriff freizuschalten: Field.setAccessible(...).

In Java umfassen die Reflection auch die Aktivierung von Klassen über den Klassenloader und deren Instanziierung. So kann eine Funktionalität in einem Java-Programm rein über externe textuelle Steuerung beeinflusst werden. Eine entsprechende symbolisch benannte Klasse muss lediglich im Klassenpfad (CLASSPATH) auffindbar sein. Sie wird bei Bedarf geladen und kann aus fest programmiertem Code angesprochen werden, wenn sie ein bestimmtes Interface implementiert.


1.2 Reflection - Anwendungen in C und C++

Topic:.ReflectionJc.usage.Cpp.

Last changed: 2007-09-23

Für C/C++ wird hier eine Reflection-Lösung benutzt, die sich an Java anlehnt. Dabei wird nicht die gesamte Funktionalität der Reflections aus Java unterstützt, folgende Teile sind ausgenommen:

Der Klassenlader ist eine typische Eigenschaft der virtuellen Maschine und für C(++)-Anwendungen nicht zutreffend. Die Security-check.Mechanismen sind insbesondere für den Einsatz von Java in unbekannten entfernten Umgebungen (Internet-Applikationen) gedacht und ebenfalls nicht zutreffend. Die strenge Unterscheidung der Zugriffsrechte sind ein Grundkonzept der Kapselung in der Objektorientierung. So ist es in Java zwar möglich, zu erfahren, dass es ein bestimmtes private-Attribute gibt, jedoch der Zugriff darauf wird mit einer Security-Exception beantwortet. Für die C(++)-Anwendung ist diese strenge Kapselung gelockert, in die Verantwortung des Anwendungsprogrammierers gelegt.

Die drei Hauptklassen der Reflections sind:


1.3 Zugriff auf Reflectiondaten

Topic:.ReflectionJc.usage.reflAccess.

Last changed: 2013-12-09

Die Reflectiondaten sind nur sinnvoll nutzbar im Zusammenhang mit Datenstrukturen. Im Embedded Bereich insbesondere bei kleineren oder älteren Anwendungen ist es häufig üblich, nur globale Variable zu verwenden, die dann im Mapfile auffindbar sind. Für solche Anwendungen ist die Reflectionlösung zu hoch gegriffen.

Wenn die Adresse einer Datenstruktur (C-struct oder C++-class) bekannt ist, dann muss zu dieser Struktur auch die Reflection bekannt sein. Dann sind die Elemente der Struktur bekannt und auswertbar.

Sind Daten strukturiert global im Speicher vorhanden, dann können die Reflection auch außerhalb des Zielsystems (target) also nur beim Zugreifenden bekannt sein, beispielsweise gebildet aus Listing- und Map-File-Informationen. Es muss dann eine Zuordnung geben Adresse im Target - Reflection.

In größeren Embedded-Applikationen werden die Daten häufig beim Hochlauf dynamisch angelegt. Entweder sie werden im Heap allokiert oder es ist eine spezielle Speicherverwaltung eingebaut. Es ist möglich, dass die Speicheradressen vom Ausbau eines Gerätes, von Startparametern oder aus anderen Gründen variieren. Dann ist eine feste Zuordnung Speicheradresse - Reflection nicht mehr möglich.

Es sind zwei Ansätze zur Reflectionzuordnung möglich, die beide praxisbewährt sind:

Wenn bei der Lösung b) eine Datenreferenz nicht auf den in den Reflection angegebenen Typ zeigt sondern die referenzierten Daten einen anderen struct-Typ haben, dann läuft dieses System an dieser Stelle auseinander. Dann läuft aber auch in der Funktionalität etwas auseinander, es sei denn die Programmierer geben einen falschen Typ in der Referenz an und gleichen dieses Problem mit einem regelmäßigen Pointercasting vor Benutzung des Referenzzeigers aus. Für einen solchen Programmierstil sind die Reflection allerdings nicht geeignet.

Die Lösung a) unterstützt den Zugriff auf Daten, die in der Referenz als Basiszeiger (Interfacezeiger, Basisklasse, super class) angegeben werden und tatsächlich umfassender sind. Die Lösung b) ermöglicht dann nur den Zugriff auf Daten der Basisklasse.

Die Lösung a) ermöglicht den Signifikanztest der Daten, indem Referenztyp und Instanztyp miteinander verglichen wird. Außerdem lassen sich neben den Reflection in die Object-Basisklasse noch weitere Signifikanztests unterbringen. Man kann damit bei versehentlich fehlerhafter Software diese Fehler aufspüren. Das dürfte für die casting-gefährdete C-Programmierung mindestens interessant sein.

Die Lösung b) hat sich allerdings in der Praxis für C-Programmierung mit quasi statischen nichtabgeleiteten Strukturen bewährt. Es sind damit vom Verfasser des Artikels komplexe kommerzielle Anlagen ausgerüstet worden, bei denen Bedienpersonal insbesondere in der Inbetriebsetzungsphase über Reflectionzugriff beispielsweise eine Feinparametrierung durchführt und Daten zwecks Analysen abgreift.

Dennoch ist Lösung a) auch für die C-Programmierung interessant und wichtig. Die Basis-Struktur für C Jc:ObjectJc und ihr C++-Äquivalent Jc:ObjectJcpp unterstützt dieses.

Die Reflection sind für eine Dateninstanz (struct oder class) als Instanz von Jc:ClassJc gegeben als Zeiger ClassJc const*.


2 Aufbau der Reflection-Daten

Topic:.ReflectionJc.ReflData.

Last changed: 2007-09-23

Die Reflectiondaten sollen im Anwenderprogramm vorliegen und eingebunden werden. Grundsätzlich besteht aber auch die Möglichkeit, die Reflectiondaten außerhalb beispielsweise in einer Datei zu halten. Das ist interessant für den Fall, dass Daten übertragen und gespeichert werden, und mit den Daten die zugehörigen Reflection-Infos. Dabei muss aber beachtet werden, dass die Reflectiondaten selbst verzeigert sind (Klasse zeigt auf ihre Attribut-Informationen, Attribut-Informationen zeigt auf die Klassen entsprechend dem Attributtyp usw.). Die Verzeigerungen sind im Anwenderprogramm vom Linker vergebene Speicheradressen. Diese Verzeigerung muss dann nachvollziehbar und im Zielsystem nachgezogen werden. Dafür sind Vorkehrungen getroffen.


2.1 Alle Daten sind Konstante

Topic:.ReflectionJc.ReflData.const.

Last changed: 2007-09-23

Grundsätzlich sind die gesamten Reflection-Infos als Konstante ausgeführt. Das bedeutet, dass kein zusätzlicher Code zum Erstellen der Daten, auch nicht beim Hochlauf nötig ist. Wichtiger ist gegebenenfalls noch, dass diese Konstanten sich auch in einem ROM-Bereich befinden können. Das ist wichtig, weil


2.2 Daten in Headerfiles definieren

Topic:.ReflectionJc.ReflData.header.

Last changed: 2013-12-09

In C ist es teilweise üblich, nur in einem C-File verwendete Daten dort im C-File als Struktur zu definieren. Nur wenn die Daten in mehreren Compilierungseinheiten (C-Files) verwendet werden, werden sie in einem Headerfile definiert.

Es ist aber durchaus angebracht, Datendefinitionen und Programmcode schon aus dokumentarischen und softwarestilistischen Gründen zu trennen. Also Datenstrukturen grundsätzlich in Headerfiles zu definieren - weil sie Datendefinitionen sind und keinen Code erzeugen. Der Sichtbarkeit - private Kapselung für C - ist damit Genüge getan, dass die Strukturen nicht in irgendwelchen globalen Headerfiles definiert werden sondern sehr geordnet in Headerfiles, die nur bestimmte, oder nur ein C-File includiert, wenn sie nur für diese Compilierungseinheit sichtbar sein sollen. Das ist softwarestilistisch Datenpflege.

Die automatische Reflectiongenerierung hat damit dann ein leichteres Vorgehen: Es werden aus allen Headerfiles die Reflection generiert.


3 C-File mit den Konstantendefinitionen

Topic:.ReflectionJc.constReflection.

Last changed: 2007-09-23

Die Konstantendefinitionen erfolgen nach folgendem Schema (gilt für manuell erstellte Reflection ebenso wie für die Generierung):

 #define protected public  //only active inside this compilation unit
 #define private public    //  to enable the access to all elements.
 #include "Jc/ReflectionJc.h"
 #include "User.h"         //The file where the data are defined.
 //...
 extern const ClassJc reflection_User_XYZ
 const struct Reflection_Fields_UserABC_t
 { ObjectArrayJc head;
   FieldJc data[2];
 } reflection_Fields_UserABC =
 { CONST_ObjectArrayJc(FieldJc, 2, OBJTYPE_FieldJc, null,
                      &reflection_Fields_UserABC)
 , {
     { "intValue"
     , 0 //nrofArrayElements
     , REFLECTION_int32
     , (4<<kBitPrimitiv_Modifier_reflectJc) //bitModifiers
     , (int16)((int32)(&((UserABC*)(0x1000))->intValue) -
               (int32)(UserABC*)0x1000)
     , 0  //offsetToObjectifcBase
     , &reflection_UserABC
     }
   , { "reference"
     , 0 //nrofArrayElements
     , &reflection_UserXYZ
     , 0 //bitModifiers
     , (int16)((int32)(&((UserABC*)(0x1000))->reference) -
               (int32)(UserABC*)0x1000)
     , 0  //offsetToObjectifcBase
     , &reflection_UserABC
     }
 } };
 //
 const ClassJc reflection_UserABC =
 { CONST_ObjectJc(OBJTYPE_ClassJc + sizeof(ClassJc)
                 , &reflection_UserABC, null)
 , "UserABC"
 , 0
 , sizeof(userABC)
 , (FieldJcArray const*)&reflection_Fields_UserABC
 , null  //method
 , null  //superclass
 , null  //interfaces
 , 0
 };

Das Beispiel definiert die Reflections für eine struct oder class mit dem Name UserABC, die 2 Elemente enthält, darunter eine Referenz auf UserXYZ. Zunächst werden die FieldJc-Elemente definiert, und zwar als Array mit Kopfdaten. Die Anzahl der Elemente, hier 2, muss zweimal angegeben werden. Die Angaben der eigenen Adresse &reflection_Fields_UserABC wird durch das Makro CONST_ObjectArrayJc passend umgesetzt. Die eigene Adresse steht aus zwei Gründen in den const-Daten:

Wesentlich ist die Offsetbildung der Daten im 5. Element eines FieldJc. Im Falle von abgeleiteten C++-Klassen müssen hier zusätzlich static_cast<ObjectJc> erfolgen, da der Offset auf die Position der Basisklasse ObjectJc innerhalb einer C++-class bezogen ist. Das ist in diesem Beispiel nicht dargestellt. Der Bezug auf eine fiktive Instanz auf der Adresse 0x1000 ist notwendig (0 wäre intuitiver), da ein GNU-Compiler mit einer Adresse 0 nicht arbeiten möchte.

In der folgenden Definition der konstanten ClassJc-Instanz ist die Referenz auf die Fields eingetragen. Im Beispiel werden nur Fields verwendet. Der Zugriff auf Methoden und Superclasses ist vorgesehen.

Die Reflections für die skalaren Basistypen, REFLECTION_char usw., sind in Reflection_Jc.h als Konstante im kleinen Bereich (bis max. 100) definiert und als (Class_Jc const *) umgecastet. Das hat den Vorteil, dass bei ausgelagerten Dateien diese Zeiger problemlos erkannt werden können, ohne diese Reflectiondaten selbst zu haben. Damit kommt ein Datenabbild nur mit seinen eigenen Reflectiondaten aus, wenn davon ausgegangen wird, das ein Datenabbild neben seinen eigenen Strukturen meist nur skalare Basistypen verwendet, und Zeiger auf fremde Typen (Interfaces), die dann aber sowieso nicht im Datenabbild dabei sind.

Für alle anderen Typen muss der Linker die Definition des jeweiligen Types, enthalten in irgendeinem compilierten C-Files wenn ein komplexes System vorliegt, finden.


4 Automatische Generierung von Reflection aus Headerfiles

Topic:.ReflectionJc.genReflection.

Last changed: 2009-09-23

Die Reflection enthalten keine andere Information, als der Compiler aus den Informationen in Headerfiles sie zusammenstellt. Es wäre zusätzliche Mühe, diese Codes mit der Hand schreiben zu müssen. Daher gibt es folgendes Verfahren zur Generierung der .c und .h-Files:

Der Headerfile, der Anwender-Datenstrukturen beschreibt, muss in seiner Syntax den Anforderungen des ZBNF-Scripts Cheader.zbnf entsprechen. Das sind keine wesentlichen Einschränkungen. Wenn ein Headerfile komplexe define-Strukturen enthält, dann ist er gegebenenfalls erst nach dem Präprozessordurchlauf des Compilers syntaktisch fassbar. Das sollte vermieden werden.

Der Inhalt des Headerfiles wird mit einem ZBNF-Parser und der ZBNF-Syntaxbeschreibung geparst, mit einem Java-Programm werden dann die Reflection.c-Files generiert.


5 Zugriff auf Daten in Anwenderstrukturen unter Nutzung der Reflection

Topic:.ReflectionJc.ifcUserData.

Last changed: 2009-09-23

.


5.1 Erhalt der Reflection-Info ClassJc zu Anwenderdaten

Topic:.ReflectionJc.ifcUserData..

Last changed: 2007-09-23

Die zugehörigen Reflection-Informationen zu Anwenderdaten sind auf folgende Weise zu erhalten:

In beiden Fällen gilt, das falsche Reflection-Daten selbstverständlich falsche Zugriffe nach sich ziehen. Das gilt insbesondere für den zweiten Fall, da hier eine Fehlerfortpflanzung möglich ist. Solche Fälle können auftreten, wenn eine Datenstruktur geändert ist, der Reflectionfile wurde aber nicht neu compiliert. Das ist ein Fehler im Make-Prozess, der auch an anderen Stellen fatal ist und ausgeschlossen werden sollte. Ein Verschreiber des Anwenders (Reflection-Typ verwechselt) ist freilich ähnlich fatal wie eine Verwechslung bei einem cast. In einer ordnungsgemäß compilierten Software ist das Verfahren fehlerfrei.


5.2 Erhalt der ReflectionInfo FieldJc oder MethodJc zu einer gegebenen ClassJc

Topic:.ReflectionJc.ifcUserData..

Last changed: 2007-09-23

Wenn den Name eines Element in der Klasse oder struct vorgegeben ist, dann kann mit Aufruf von

 FieldJc const* field = getDeclaredField_ClassJc
                       (clazz, StringJc* sName);

das benannte Element (Attribut oder Referenz) gesucht werden. Die Suche ist eine Iteration über alle Fields der ClassJc und dauert eine kurze Zeit. Das Ergebnis ist die FieldJc-Instanz im const-Bereich. Dieser Zugriff erfolgt nur unter Kenntnis der ClassJc, unabhängig von den Anwenderdaten. In Java gibt es die adäquate Methode. Auch in Java werden dabei Fields auch mit private-Kapselung gefunden.

Wenn das erforderliche Element nicht vorhanden ist, dann wird eine Exception NoSuchField erzeugt. Das ist adäquat Java. Der Anwender sollte also um diese Methoden ein TRY-CATCH anordnen, wie es in Kapitel beschrieben ist.

Unter Kenntnis der Instanz FieldJc können nun die weiteren statischen Eigenschaften des Fields wie Typ, Sichtbarkeit, Modifikatoren getestet werden. immer noch ohne auf Anwenderdaten zuzugreifen.

Ein Array aller Fields bekommt man mit dem Aufruf von

 FieldJcArray const* fields = getDeclaredFields_ClassJc(clazz);

Damit kann über alle Fields iteriert werden. Ein FieldJcArray basiert auf ObjectArrayJc, die Anzahl der Fields kann also über fields->head.lenght ermittelt werden, die einzelnen FieldJc sind über fields->data[...] erreichbar.


5.3 Zugriff auf Datenfelder in Anwenderinstanzen

Topic:.ReflectionJc.ifcUserData..

Last changed: 2007-09-23

Mit den korrekten Reflection-Informationen FieldJc und dem Zeiger auf die Anwenderdaten kann auf die Attribute der Anwenderinstanz zugegriffen werden. Dabei muss die Referenz auf die Anwenderdaten auf die Adresse der ObjectJc-Basisklasse angegeben werden, wenn diese auf ObjectJc basiert. Damit ist ein static_cast<ObjectJc*>(instance) notwendig bei gegebener Instanzadresse. Die Methoden für Datenzugriffe von FieldJc übernehmen einen void-Zeiger, damit werden keinerlei Prüfungen zur Compilezeit ausgeführt. Der void-Zeiger ist aber deshalb notwendig, weil auch auf Instanzen zugegriffen werden soll, die nicht auf ObjectJc basieren. Im allgemeinen C/C++-Umfeld kann eine Vererbung von ObjectJc als wesentlichstes Paradigma nicht erzwungen werden, da mit Fremdcode auch umgegangen werden muss. Der Zwang zur fehlerfreien Programmierung ist der selbe, wie er etwa bei Operationen wie memcpy oder C-castings bzw. reinterpret_cast angewendet werden muss.

Lesen von Werten wie in Java:

Die letzte Methode enthält einen Index, den es in Java nicht gibt. Ist das Datenelement kein Array, dann muss hier -1 übergegeben werden. Die Nutzung eines solchen Index sollte auch auf die anderen oben genannten Methoden erweitert werden.

Setzen von Werten wie in Java:

Zugriffe für C/C++-Belange als Erweiterung

Die folgenden Methoden gibt es in dieser Art nicht in Java. Sie sind für die Datenanalyse in C/C++ notwendig:

Verfahrensweise bei Arrays und Containern

In Java müssen Arrays und Container manuell durchsucht werden. Bei einem Array kann man immer die Länge ermitteln, unabhängig von dessen Typ. Der Elementtyp eines Arrays ist aus der Abfrage der ClassJc des Arrays ermittelbar. Dann kann ein gezielter Zugriff auf die Elemente erfolgen, wie am Beispiel des folgenden Java-Codes gezeigt wird:

 int[] testArray = new int[10]; //the users program
 //
 //inspect it:
 Object inspectObj = testArray; //type unknown...
 Class clazz = inspectObj.getClass();
 String clazzName = clazz.getName();
 if(clazzName.equals("[I"))
 { //it is an integer array:
   int[] inspectInt = (int[])inspectObj; //cast
   int length = inspectInt.length;
   inspectInt[length-1] = 333;
 }

Handelt es sich um ein Array von Referenzen auf eine Klasse, dann wird als Name "[L..." angegeben. Das L steht für Object, danach folgt die Typbezeichnung der Referenzen des Arrays. Das ist lediglich eine Zusatzinformation. Auf die Array-Elemente muss nun ähnlich dem int[]-Beispiel zugegriffen werden, wobei die Zielreferenz entweder zum angegebenen Typ passen muss oder Object ist. Von diesem Object kann dann wieder die tatsächliche getClass() ermittelt werden, eine abgeleitete Instanz ist möglich.

Handelt es sich um einen Container wie List dann muss auf den Container entsprechend zugegriffen werden, um danach die Class der Elemente zu ermitteln.

Dieses Verfahren ist umständlich aber vollständig. In C/C++ ist es deshalb nicht allgemein anwendbar, weil es in C/C++ eine größere Vielfalt von Möglichkeiten der Gestaltung von Arrays gibt. Instanzen in Arrays oder Container sind nicht immer von Object abgeleitet. Es gibt es auch den typischen Fall der embedded Arrays wie

 typedef struct MyStruct_t{ int a; float b;}MyStruct;
 MyStruct array[25];

Hierbei kann ein allgemein programmierter Zugriff nur über sizeof-Kenntnis und Adressrechnung erfolgen, weil ein casting dort nicht erfolgen kann.

Die Vielfalt der Gestaltung von Arrays und Containern wäre nur durch aufwändigere Anwenderprogrammierung als in Java zu lösen, dabei müssen die Eigenschaften der Arrays jeweils spezifisch aus den Reflection ermittelt werden. Das Verfahren ist auch nicht Java-kompatibel Daher wurde die Array/Container-Erkennung und deren Auflösung in die Grundfunktionen von FieldJc eingebaut. Ein Zusatzparameter idx sorgt für eine entsprechende Indizierung eines Elementes in einem Array oder Container. In den Reflection wird getestet, ob es sich um ein statisches Array oder um ein embedded Array fester Größe handelt. Dann ist in der jeweiligen Methode die Adressrechnung intern möglich, da die Feldgröße und Byteanzahl in den Reflection steht. Handelt es sich um ein dynamisches Array des Grundtyps ObjectArrayJc dann ist die Größe in dessen Kopfdaten ermittelbar. Auch bestimmte Typen von Containern werden berücksichtigt, wobei die Container eines UML-Frameworks mit zusätzlich zugelinkten Methoden einbezogen werden können. Die Information über den Containertyp steht in den Reflection. Die Anwenderprogrammierung ist damit wesentlich vereinfacht. Für den Fall von Object-basierenden abgeleiteten Klassen kann wie in Java von der Referenz des Array- oder Container-Elementes dessen ClassJc bestimmt werden. Das wird aber insgesamt von der oben genannten Methode getClassAndObj_FieldJc(...) ausgeführt, die von get_FieldJc() intern gerufen wird. Die Indizierung wurde derzeit noch nicht bei den set- und get-Methoden für skalare Werte ausgeführt, sollte aber als Erweiterung genauso ausgeführt werden. Damit ändern sich die Signaturen der get- und set-Methoden auf skalare Werte um diesen zusätzlichen Parameter. Ein doppelter Satz von Methoden mit oder ohne Index ist nicht empfehlenswert, da damit die Anzahl der Methoden zunimmt, andererseits mit dem idx=-1 immer eine Kompatibilität zum nichtindizierten Fall durch einfache Quellenänderung herstellbar ist.

Um solche Funktionalitäten kompatibel auch in Java abzubilden (Javalike-Konzept), ist dort eine entsprechende Klasse als Erweiterung zu java.lang.reflection.Field möglich (org.vishia.bridgeC.FieldJc) , so dass die C-Erweiterungen wieder in Java ähnlich anzutreffen sind.


6 Detaildarstellung Zugriffe auf Anwenderdaten

Topic:.ReflectionJc.accessToUserDataViaReflection.

Last changed: 2007-09-23

Bei den Datenzugriffen wird die Referenz auf die Instanz als Argument angegeben. In C ist auch bei C-like-Interfaces der Zeiger auf die Instanz immer identisch mit dem Zeiger auf die Basisklasse Object_Jc. Bei den Datenzugriffen auf Feldelemente, die selbst nicht auf Object_Jc basieren, sondern nur deren Feld-Kopfstruktur ObjectArrayHead_Jc, ist der Zeiger auf die Instanzdaten nicht auf Object_Jc* konvertierbar. Daher wird bei den Methoden des Zugriffes für C wie

 METHOD_C int getInt_Field_Jc(const Field_c* ythis, void* obj);

der Zeiger auf die Instanz in der Form void* übergeben, siehe Abschnitt "Zugriff auf Daten von Arrays ohne Reflectioninfo der einzelnen Elemente"

Bei C++ ist dagegen der Zeiger auf die Instanzdaten meist nicht identisch mit dem Zeiger auf die Basisklasse ObjectJc. Es wäre eher ein Zufall bzw. es ist nur garantiert bei einfachen Klassen, die nur auf ObjectJc basieren. Eine Referenz kann vom Typ eines Interfaces auf eine Instanz sein. In diesem Fall zeigt die Referenz auf die Daten des Interface, beginnend mit dessen virtueller Tabelle inmitten der Instanzdaten, an der das Interface angeordnet ist.

Das nachfolgende Schema zeigt ein Speicherlayout, entnommen dem TestReflection.* für die Instanz myData. Für den Aufruf per Interface kennt die aufgerufene Methode, im Bespiel accessViaInterface(MyInterface* refIfc) die Daten ab der Position refIfc. Dort steht die virtuelle Tabelle des Interfaces und danach etwaige Daten der Interfaceklasse (wenn es kein reines Interface ist). Diejenigen Methoden, die in MyData überladen sind, kennen den Offset zwischen MyData und MyInterfaceBase und korrigieren den this-Zeiger um -8. Das leistet der C++-Compiler.

 myData: 9C 99 43 00 MyData::vtbl
         DA DA 5E BA       :;baseData
 refIfc: 90 99 43 00 MyInterfaceBase::vtbl
         80 99 43 00 ObjectifcBaseJcpp::vtbl
         5E BA FC 0E                  ::significance
         0C 3E 33 00                  ::significanceAddress
 333E18: 00 00 31 02 ObjectJc::objectIdentSize
         18 3E 33 00         ::ownAddress
         CD CD FF FF         ::idSyncHandles
         C0 FA 43 00         ::reflectionClass
         70 3E 33 00 MyData::refData

Damit mit Reflection gearbeitet wird, ist die Referenz auf ObjectJc notwendig. Diese steht zwar kurz dahinter, aber die Position hängt von der Datenkonstellation insgesamt ab. Keine Zeigerarithmetik kann diese bestimmen, sondern nur der Aufruf der Methode

 ObjectJc* obj = refIfc->toObject();

die im Basis-Interface ObjectifcBaseJcpp von MyInterface definiert ist und mit

 ObjectJc* MyData::toObject(){ return this; }

implementiert ist. Dieses return this gibt nicht den original übergebenen this-Zeiger zurück, sondern addiert den Offset, um die Basisklasse ObjectJc zu referenzieren, wie es der return-Typ verlangt, ein implizites cast. Das leistet der C++-Compiler. Mit der Referenz auf die ObjectJc-Basis können nun reflection-Methoden gerufen werden:

 ClassJc const* clazz = getClass_ObjectJc(obj);
 char const* clazzName = getName_ClassJc(clazz);
 StringJc fieldName = s0_StringJc("refData");
 FieldJc const* field = getDeclaredField_ClassJc(clazz, &fieldName);
 void* refAddr = getMemoryAddress_FieldJc(field, obj);
 void* refPoor = getRefAddr_FieldJc(field, obj, -1);
 void* refObj;
 ClassJc const* clazzField =
   getClassAndObj_FieldJc(field, obj, -1, &refObj);

In diesem Beispiel wird eine Referenz auf ein Interface MyInterface ermittelt, diese Referenz zeigt im Beispiel auf eine Instanz von MyData2. Die drei Zeiger verdeutlichen das C++-typische Speicherlayout hier von der Instanz von MyData2:

 myData2:E8 99 43 00  MyData2::vtbl
         DA DA 5E BA        :;baseData
 refPoor:DC 99 43 00  MyInterfaceBase::vtbl
 333E74: CC 99 43 00  ObjectifcBaseJcpp::vtbl
         5E BA FC 0E                   ::significance
         74 3E 33 00                   ::significanceAddress
 333E80: 00 00 34 02  ObjectJc::objectIdentSize
         80 3E 33 00          ::ownAddress
         CD CD FF FF          ::idSyncHandles
         10 FB 43 00          ::reflectionClass
         56 34 12 A0  MyData2::value

MyData2 hat im Beispiel ein ähnliches Speicherlayout. Die refAddr aus den obigen Anweisungen ist diejenige, auf der die Referenz steht. Es ist der Wert0x333E28 der im oberen Speicherlayout zu finden ist. Dort steht die Referenz mit dem Wert 0x333E70, in refPoor gespeichert. Um von dieser Adresse ausgehend weiterhin mit Reflections zu arbeiten, muss man irgendwie geeignet die Adresse des ObjectJc-Anteils der Instanz zeigern. Es ist allerdings so, dass im Umfeld des C++-compilierten Codes der Typ der Referenz nicht bekannt ist. Es handelt sich um ein void*, der durch Lesen der Referenz ermittelt wird. Der Typ steht allerding in der zuständigen FieldJc-Instanz, hier field, und zwar im Typ des Fields. Dieser ist reflection_MyInterface. Für diesen Typ ist bekannt, dass er auf ObjectifcBaseJcpp basiert, entsprechend der Notation im Headerfile. In den ClassJc-Daten für reflection_MyInterface ist sowohl das entsprechende Bit in modifiers gesetzt, als auch das Datenelement posObjectBase ist gesetzt mit dem Wert 0x0004. Der Wert ergibt sich bei der Compilierung der generierten Reflection aus dem Ausdruck

 (int)(static_cast<ObjectifcBaseJcpp*>((MyInterface*)0x1000)) - 0x1000

Der Ausdruck wird vom Compiler als Konstante berechnet mit den gleichen Bedingungen, wie anderer Code compiliert wird.

Mit diesen Informationen kann nun eine Adresskorrektur des void*-Zeigers der Referenz um 4 und ein nachfolgendes cast auf den Typ ObjectIfcBaseJcpp erfolgen. Die Korrektur und cast-Aktion wird innerhalb der Routine getClassAndObj_FieldJc(...) ausgeführt:

 ObjectifcBaseJcpp* objifc = (ObjectifcBaseJcpp*)
                             ((MemUnit*)(ref) + offsetBase);

Eine Adresskorrektur und ein hartes cast ist allerdings eine Vermutung, dass alle Daten richtig sind. Wenn im Anwenderprogramm ein Fehler vorliegt, dann würde der nachfolgende Aufruf

 retObjBase = objifc->toObject();

zu einem fatalem Absturz führen, da der Maschinencode über den Speicherinhalt die virtuelle Tabelle aufsucht und dort einen indirekten Call ausführt. Im Speicher kann im Grunde genommen irgend etwas stehen, erzeugt durch gegebenenfalls einen Anwenderfehler. Ein durchaus typischer anderer Anwender-Fehler ist, dass die Compilierung der Reflection-Information möglicherweise nicht aktuell ist, da das Make-System nicht korrekt arbeitet. Daher ist vor dem Aufruf ein Sicherheitscheck eingebaut, der kaum Rechenzeit benötigt aber den letzteren Fehler entdeckt und Datenfehler mit einer höhereren Wahrscheinlichkeit entdeckt: Im ObjectIfcBaseJcpp sind zwei Datenzellen enthalten, die einerseits eine signifikante Belegung 0xefcba5e und andererseits die eigene Speicheradresse enthalten. Das ist im obigen Memory-Layout erkennbar. Bei dem Signifikanz-Wert kann man ifcbase lesen, wenn man das e als i und die 5 als s liest. Das ist im Debugmodus eine kleine Merkhilfe. Die Wahrscheinlichkeit, dass bei einem Datenfehler diese 2 Belegungen korrekt sind, aber die vtbl-Adresse falsch, ist mindestens 1 : 3.

Nach diesem Signifkanz-Check kann nun objifc->toObject() gerufen werden und damit über die korrekte Implementierung dieser Methode in der instanziierten Klasse der ObjectJc-Zeiger ermittelt werden.

Wenn eine Referenz vorliegt von einen Typ, der auf ObjectJc selbst basiert, dann ist das Verfahren adäquat. Das entsprechende Bit in den ClassJc des Referenztyps ist gesetzt, und der Offset zu ObjectJc ist bekannt, beispielsweise für den Typ MyData mit

 (int)(static_cast<ObjectJc*>((MyData*)0x1000)) - 0x1000

niedergelegt. Ein Signifikanztest ist auch hier möglich, weil in einem ObjectJc im Datenlement ownAddress immer die selbe Speicheradresse stehen soll, auf der ObjectJc liegt. Dieser Signifikanztest ist derzeit nicht aktiv, weil diese Festlegung ggf. nicht in allen Produktiv-Codes derzeit beachtet wird (TODO). Es ist allerdings auch hier nicht so kritisch, da keine Methode gerufen wird sondern im Fehlerfall lediglich ein falscher Zeiger auf ClassJc ermittelt wird. Dieser ist einerseits auch signifikanz-testbar, andererseits gibt es dann falsche Anzeigen, die von der Anwendung bemerkt werden. Der scharfe Signifikanztest sollte hier per Compileroption abschaltbar sein wo nötig und ansonsten erfolgen (TODO).


7 Methoden in Reflection

Topic:.ReflectionJc.accessToMethod.

Last changed: 2007-09-23

Der Zugriff auf Methoden in Reflection ist derzeit nicht aktiv genutzt und getestet. Die Vor-Überlegungen und -Untersuchungen und vorhandene Codes sollen allerdings hier dargestellt werden.

Die relevante Struktur ist struct:_MethodJc, der Zeiger auf ein Array von methoden in ist struct:_ClassJc als

 MethodJcARRAY const* methods;

enthalten. Allerdings werden Methoden bei der automatischen Reflection-Generierung aus Headerfiles derzeit nicht unterstützt.

Die Methoden sind in MethodJc aufgeführt als

 Object__VoidMethod adress;

Das ist die Startadresse. Derzeit nicht ausreichend berücksichtigt sind rein abstrakte virtuelle Methoden von Interfaces, insbesondere nicht Methoden eines C-like-Interfaces über eine Mtbl (Methodentabelle).

Die Startadressse ist zwecks einheitlicher Speicherung auf den dargestellten Zeiger auf eine void-Methode gecastet, in C++ mit

 typedef void(ObjectJc::*Object__VoidMethod)();

definiert, für C mit

 typedef void (*Object__VoidMethod)();

Die Parameterabhängigkeit ist etwas vereinfacht aufgeführt, und zwar mit einem

 Type_MethodJc eType;

Die zugehörige enum-Definition

 typedef enum Type_MethodJc_t
 { kNothing_Method
 , kInt_void, kInt_Int, kInt_2Int, kInt_3Int, kInt_Float, kInt_2Float
 , kFloat_void, kFloat_Int, kFloat_2Int, kFloat_3Int
 , kFloat_Float, kFloat_2Float
 , kVoid_void, kVoid_Int, kVoid_2Int, kVoid_3Int, kVoid_Float, kVoid_2Float
 }Type_MethodJc;

berücksichtigt typische Konstellationen, aber nicht alle. Der Gedanke hierbei ist: Methoden über Reflection sind nur dann zweckmäßig, wenn es einfache von außen aufrufbare Methoden sind. Diese dürften kaum referenzierte Daten benötigen, sondern eine Kombination von skalaren Werten. Die Kombinationen sind aber nicht hinreichend. Hier kann eine bessere Auswahlmöglichkeit für zukünftige Entwicklungen zweckdienlich sein. Erste Erfolge sind mit dem hier vorgestelltem System jedenfalls möglich.

Die entscheidende Methode für den Aufruf ist adäquat zu Java

 invoke_v_MethodJc(const MethodJc* ythis, void* obj, int32ARRAY* params);

Die Parameter sind hier wieder auf eine einfache Art übergeben, ein Ausbau ähnlich wie in Java wäre denkbar. Der Zeiger auf die Anwender-Instanz wird als void* übergeben, weil auch hier nicht vorausgesetzt wird, dass alle Instanzen auf ObjectJc basieren. Wie bei den FieldJc-Zugriffen ist der Anwender für die Korrektheit des Zeigers verantwortlich bzw. Suchfunktionen sorgen für eine entsprechende Korrektur aufgrund der gegebenen Reflectiondaten ähnlich wie bei getClassAndObj_FieldJc(..).

Der Aufruf invoke_v_MethodJc(...) ist in C ein einfacher Aufruf über einen Funktionszeiger. In C++ muss die Instanz mit übergeben werden. An dieser Stelle ist noch Klärungsbedarf (TODO).


8 Zugriff auf Basisklassen und Interfaces

Topic:.ReflectionJc.accessToIfc.

Last changed: 2007-09-23

Der Zugriff auf Interfaces und Basisklasse in Reflection ist derzeit aktiv genutzt für den Aufruf von Methoden über das C-Interface, für Datenzugriffe aber derzeit niht genutzt und getestet.

Der Zeiger auf ein Array von Interfaces in ist struct:_ClassJc als

 struct ClassOffset_idxMtblJcARRAY_t const* superClasses;
 struct ClassOffset_idxMtblJcARRAY_t const* interfaces;

enthalten. Sowohl Interfaces als auch Basisklassen werden als Array gefürt. Javalike müsste es nur eine Basisklasse geben, das ist aber in einigen C++-Anwendungen nicht so. Daher wurde auch hier auf ein Array orientiert. Diese Arrays werden bei der automatischen Reflection-Generierung aus Headerfiles derzeit nicht unterstützt, sind allerdings in einigen manuell erstellen Reflection getestet.

Der Typ ClassOffset_idxMtblJc, auf dem dem Array-Typ basiert, ist wie folgt definiert:

 typedef struct ClassOffset_idxMtblJc_t
 {
   /** The reflection definition*/
   ClassJc const* clazz;
   /** Index of the virtual table inside its parent.*/
   int idxMtbl;
 }ClassOffset_idxMtblJc;

Der zweite Parameter dieser Struktur ist entscheidend für das dynamische Binden in C. Dieses läuft insbesondere über die Reflection-Daten und ist gesondert in Topic:_DynamicCallInC dargestellt.


9 Zugriff auf Daten von Arrays ohne Reflectioninfo der einzelnen Elemente

Topic:.ReflectionJc.oldoldold.

Last changed: 2007-09-23

In Java sind alle Feldelemente, die keine einfache skalare Variable darstellen (int, float, ...), grundsätzlich über Referenzen geführt. Die referenzierten Instanzen erben von Object und sind demzufolge mit Reflections zugänglich. Beispiel:

 final class Data
 { int a;
   float f;
 }

 ...
 Data[] dataArray = new Data[12];

In dem gezeigtem Beispiel wird nicht etwa, wie in C(++) zu erwarten, ein Feld mit 12 Elementen vom Typ Data angelegt, sondern es wird nur ein Feld mit 12 nichtinitialisierten Referenzen angelegt. Würde Data nicht final sein, so könnten dort auch von Data abgeleitete Klassen referenziert werden. Um die Feldelemente tatsächlich anzulegen, ist nochmal Arbeit erforderlich:

for(int i = 0; i < dataArray.length(); i++){ dataArray[i] = new Data(); }

Erst damit bekommt man das in C erwartete Ergebnis. Java ist hier etwas komplizierter, aber dafür universell und sicher. Das entspricht dem Referenzkonzept, Java kennt keine "eingebetteten Daten", in C(++) sind eingebetteten Daten dagegen oft erwünscht und durchaus oppurtun. Ein Feld aus zusammengesetzten Elementen soll direkt angelegt werden:

 typedef struct Data_t
 { int a;
   float f;
 }Data;

 Data* dataArray = new Data[12];  //(C++)
 Data* dataArray = (Data*)(malloc(12*sizeof(Data));  //C-Variante

Dieses einfache und übliche Konstrukt aus C kennt jedoch weder eine Basisklasse Object, damit keine Reflection, noch ist eine Information über die Anzahl der Feldelemente direkt mit dem Feld verbunden vorhanden (muss geeignet extra programmiert werden).

Basisklasse ObjectArrayHead_Jc ist zu verwenden

Aus obigen Grund ist in der CRuntime_Javalike eine Basisklasse ObjectArrayHead_Jc definiert. Diese enthält die Kopfdaten eines beliebigen Feldes und ist von Object_Jc abgeleitet. Es ist möglich, dass die Feldelemente unmittelbar nach den Kopfdaten folgen.Dann bekommt man eine ähnlich kompakte Datenstruktur wie man es von C aus gewöhnt ist. Auf dieser Basis arbeitet das Reflectionprinzip für Arrays. Beispiel:

 typedef struct Data_t
 { int a;
   float f;
 }Data;


 typedef struct DataArray_t
 { ObjectArrayHead_Jc array;
   Data data[100];    //NOTE: 100 is only a debug size, use dynamic size, see sizeof_DataArray.
 }DataArray;

 /*Constructor sets default values at the elements and set the head data of array.*/
 DataArray* constructor_DataArray(DataArray* ythis, int size);

 #define sizeof_DataArray(SIZE) (sizeof(ObjectArrayHead_Jc) + SIZE * sizeof(Data))

 #define new_DataArray(SIZE) constructor_DataArray( (DataArray*)malloc(sizeof_DataArray(SIZE)), SIZE ))


 DataArray* dataArray = new_DataArray(12);

Im Speicher werden die Kopfdaten und die angegebene Anzahl von Feldelementen des Typs Data in einem Block hintereinander angeordnet. Das ist die Basis für Reflections auf Arrays.

In C: Die Reflections des Arraytypes enthalten die Informationen der Elemente In Java enthält die Reflectioninformation (Class) einer Feldinstanz lediglich den Namen des Feldes, keine weiteren Informationen. Auch das Attribut length, Bestandteil jeder Arrayinstanz, wird in den Reflections nicht angezeigt. Es ist selbstverständlich.

 final class Data
 { int a;
   float f;
 }

 ...
 Data[] dataArray = new Data[12];
 for(int i = 0; i < dataArray.length(); i++){ dataArray[i] = new Data(); }

 Class classDataArray = dataArray.getClass();
 Class classData      = dataArray[0].getClass();
 System.out.println(classDataArray.getName());
 Field[] fieldsDataArray = classDataArray.getDeclaredFields();
 System.out.println(classData.getName());
 Field[] fieldsData      = classData.getDeclaredFields();
 Field field_a           = classData.getField("a");

Die erste Ausgabe für classDataArray.getName() liefert "[Lpackage.Data" als Anzeige, das es sich um ein Feld vom Referenztyp Data handelt. Das fieldsDataArray ist ein Feld der Länge 0. Die zweite Ausgabe für classData.getName() liefert "package.Data" als Typ des Feldelementes, das fieldsData enthält die Attribute von Data.

In C(++) ist für ein mit ObjectArrayHead_Jc gebautes Feld keine Reflection für die Elemente abrufbar, statt dessen ist beides kombiniert mit

 Class_Jc* classDataArray = getClass_Object_Jc(&dataArray->array.object);
 Field_Jca* fieldsDataArray = getDeclaredFields(classDataArray);
 Field_Jc field_a           = getField_Class(classDataArray, const_String("a"));
 println_PrintStream(&System.out, getName_Class_Jc(classDataArray);

abrufbar. Die Ausgabe liefert hier wie in Java "[LData", aber fieldsDataArray enthält die Attribute des Feldelementes. Das ist möglich, da die Elemente mit genau diesem Datentyp (und im Gegensatz zu Java nicht mit einem möglicherweise abgeleitetem Datentyp oder mit null) besetzt sind.

Probleme beim Test der Gültigkeit des angegebenen Feldelementes In Java wird ein Wert eines Attributes gelesen oder gesetzt mit

 Field field_a = dataArray[0].getClass().getField("a");
 int a = field_a.getInt(dataArray[5]);
 field_a.setInt(dataArray[5], 123);

Das field_a ist dabei aus der Reflection eines Feldelementes bestimmt, aber nicht notwendigerweise aus dem des 5. Feldelementes, sondern beispielsweise aus dem ersten, da alle Elemente vom Aufbau her identisch sind. Grundsätzlich gilt in Java, dass beim Zugriff auf ein Element getestet wird, ob die angegebene Instanz dem selben Typ entspricht wie der class-Typ, der dem Field entspricht (ermittelbar auch manuell programmiert mit field_a.getDeclaringClass(). Nur so kann gesichert werden, dass keine unpassenden Instanzen beim Feldzugriff angegeben werden. Der Aufwand zur Runtime ist ähnlich kritisch/unkritisch zu bewerten wie die Tatsache in Java, dass jeder Index eines Feldes zur Runtime getestet wird. Die VM optimiert hier einiges, es handelt sich jeweils nur im Nanosekunden bei den üblichen Prozessoren.

In C(++) stehen beim adäquaten Aufruf

 Field_Jc* field_a = getField_Class_Jc(getClass_Object_Jc(dataArray),const_String_Jc("a"));
 int a = getInt_Field_Jc(field_a, dataArray[5]);
 setInt_Field_Jc(field_a, dataArray[5], 123);

die Reflection-Infos aus dataArray[i] nicht zur Verfügung, da ein Feldelement nicht auf Object basiert. Daher muss in diesem Fall der Test der Zulässigkeit des Zugriffes entfallen. Das entspricht aber dem allgemeinem Programmierparadigma in C(++). Es werden an vielen Stellen Zeiger verwendet, ohne nochmaligen expliziten Zulässigkeitstest.

Die Zulässigkeit kann per manueller Programmierung aber wie folgt getestet werden:

 if(getDeclaringClass_Field_Jc(field_a) == getClass_Object_Jc(dataArray))
 {...}

Das kann in Java ebenfalls genauso explizit erfolgen. Basis für den Test ist hier das Feld selbst, in Java steht an dieser Stelle adäquat wie oben bei der Ermittlung von field_a das Feldelement:

 if(field_a.getDeclaringClass() == dataArray[5].getClass())
 {...}

10 TODO

Topic:.ReflectionJc..

Last changed: 2007-09-23

Ablauf des Aufrufes von Methoden

Liste aller Methoden über getMethods_Class_Jc()

Suche einer Methode nach Namen und Parametertypen - getMethod(Name, Parameter)

Nichtbeachtung der Funktionsparameter - im Gegensatz zu Java

Kürzel der Funktionsparameter bei C++

Beschränkung auf einfache Methodenparameter

Aufruf von C-Methoden

Aufruf von C++-Klassenmethoden

Nutzung der Adress- und Typinformation für Methodenaufrufe anderer Art

Ermittlung der Zugehörigkeit von Basistypen und Interfaces mit instanceof_Class_Jc(Object, Class)


11 Aus Headerfiles generierte Doku

Nachfolgende Dokumentation ist direkt aus den Headerfile-Kommentierungen

       in Reflection_Jc.h generiert, daher in englisch:

UML=/Package[ReflectionJc_h]/Namespace.ownedElement[]/Class[ClassJc]

Class ClassJc im Package ReflectionJc_h

UML=/Package[ReflectionJc_h]/Namespace.ownedElement[]/Class[ClassJc]

Attributes:

+-------'-------'-------'-------'-------'-------'-------'-------+
|                            object                             |
+-------'-------'-------'-------'-------'-------'-------'--...32+
|                             name                              |
+-------'-------'-------'-------+-------'-------'-------'-------+
|        posObjectBase          |            nSize              |
+-------'-------'-------'-------+-------'-------'-------'-------+
|          attributes           |           methods             |
+-------'-------'-------'-------+-------'-------'-------'-------+
|         superClasses          |          interfaces           |
+-------'-------'-------'-------+-------'-------'-------'-------+
|          modifiers            |             mtbl              |
+-------'-------'-------'-------'-------'-------'-------'-------
Pos. 0x0..0x = 0..NaN ( NaN bytes): object : ObjectJc
Pos. 0x..0x = NaN..NaN ( 32 bytes): name : char [32]

The typename. If it is a Class represents a primitive type, the name is such as "int", "float", "boolean".

Pos. 0x..0x = NaN..NaN ( 4 bytes): posObjectBase : int32

position of the base structure/class ObjectJc inside this type, it is the base address for the offset of fields.

Pos. 0x..0x = NaN..NaN ( 4 bytes): nSize : int32

sizeof the type. Hint: It may be longer as 64 kByte, int32 is necessary.

Pos. 0x..0x = NaN..NaN ( NaN bytes): attributes : FieldJcArray
Pos. 0x..0x = NaN..NaN ( NaN bytes): methods :
Pos. 0x..0x = NaN..NaN ( NaN bytes): superClasses :

The superclass, ObjectJc if no other superclass.

Pos. 0x..0x = NaN..NaN ( NaN bytes): interfaces :

Array of interfaces to this class.

Pos. 0x..0x = NaN..NaN ( 4 bytes): modifiers : int32

Some bits determines the kind of the Class, see Modifier_reflectJc

Pos. 0x..0x = NaN..NaN ( 5 bytes): mtbl : MtblHeadJc

Pointer to jump table for dynamic calls (virtual methods). This is a typed struct, starting with Mtbl_ObjectJc.

Methoden:

ctorM_ClassJc (rawMem) : ClassJc

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 initializes a ClassJc, see [[ctorc_ClassJc(...)]].
  • rawMem: MemC - raw memory area, it may be uninitialized. The size may be greater as necessary. The constructor initializes only its own area.

  • returns: ClassJc -

  • throws - IllegalArgumentException if the sizeof rawMem is to less.

ctorc_ClassJc (ythis) : void

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 initializes a ClassJc.

All content is set to 0.

  • returns: void -

getClass_ClassJc (OBJ) :

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

  • OBJ: -

  • returns: -

getDeclaredFields_ClassJc (ythis) : FieldJcArray

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 Methods from Class
  • returns: FieldJcArray -

getDeclaredField_ClassJc (ythis, sName) : FieldJc

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

  • sName: StringJc -

  • returns: FieldJc -

getDeclaredMethods_ClassJc (ythis) :

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

  • returns: -

getDeclaredMethod_ClassJc (ythis, sName) : MethodJc

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

getEnclosingClass_ClassJc (ythis) : ClassJc

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

getName_ClassJc (clazz) : char

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 gets the Name of the class. It is a static method, because the argument class may be a constant for simple types.
  • clazz: ClassJc -

  • returns: char -

  • param - class Either the class object or a constant to design simple types, see REFLECTION_xxx.

getSuperclass_ClassJc (ythis) : ClassJc

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

getModifiers_ClassJc (ythis) : int32

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 gets the modifiers for this class or interface, encoded in an integer.

They should be decoded using the methods of class ModifierJc.

  • returns: int32 -

isPrimitive_ClassJc (ythis) : bool

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 returns true if the type is a primitive Type, like java Class::isPrimitive()
  • returns: bool -

isReference_ClassJc (THIS) :

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 returns true if the type is a reference Type. Not javalike.
  • THIS: -

  • returns: -

isObjectJc_ClassJc (THIS) :

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 returns true if the type is a instance of a C-struct, based on ObjectJc.

This method is defined outside java, in java all classes based only on Object.

  • THIS: -

  • returns: -

isObjectifcBaseJcpp_ClassJc (THIS) :

Array contains the number of byte which were used if the scalar types with designation 0..0x17 are stored in a byte structure.

see see javaSrc_vishiaBase/org.vishia.reflect.Java2C.nrofBytesScalarTypes.

 returns true if the type is a instance of a C++-class, based on ObjectifcBaseJcpp.

It may be also a reference to a interface. The reference type should based on ObjectifcBaseJcpp. This method is defined outside java, in java all classes based only on Object.

  • THIS: -

  • returns: -

CONST-Initializer:

CONST-Initializer sind Makros für C-Konstanten, sie sind in Headerfiles definiert. C-Konstante sind Konstrukte in { ... } mit ausschließlich konstanten Werten. Die Makros der CONST-Initializer übernehmen Argumente, die zur Compilezeit die Konstanten bestimmen. Die Initializer sind deshalb als Makros definiert, weil die Struktur der Konstanten exakt der struct-Definition folgen muss, die struct ist im Headerfile definiert, daher auch dazu passend diese Makros. Mit denCONST-Intializer ist es auf einfache Weise möglich, C-struct-Daten (Plain Old Data) zu initialisieren. Für Klassen (C++) ist dieses Konzept nicht geeignet.

CONST_ClassJc(SNAME, NAME)

Macro for constant value of a ClassJc inside a ReflectionImage-structure. The macro REFLECTION_IMAGE should be defined with the identifier of the reflection image.

  • SNAME -

  • NAME -

CONST_Cpp_ClassJc(SNAME, NAME, OWNADDRESS)

Adaequate complex reflection for C++-classes

  • SNAME -

  • NAME -

  • OWNADDRESS -

CONST_ObjectJc_REFLECTION_IMAGE()

Macro for constant value of the ObjectJc on head of any reflectionImage-structure. The macro REFLECTION_IMAGE should be defined with the identifier of the reflection image. Therefore all information to build the constant value is given, no additionaly arguments are needed.

CONST_dataImg_ClassJc(SNAME, NAME)

Macro for constant value of a only-data-ClassJc inside a ReflectionImage-structure. The macro REFLECTION_IMAGE should be defined with the identifier of the reflection image.

  • SNAME -

  • NAME -

CONST_data_ClassJc(SNAME, NAME)

Macro for constant value of a ClassJc inside a ReflectionImage-structure. The macro REFLECTION_IMAGE should be defined with the identifier of the reflection image.

  • SNAME -

  • NAME -

CONST_dataonly_ClassJc(SNAME, NAME)

Constant Definition of a ClassJc-instance usefull for simple plain old data without special defined methods. A superclass ObjectJc is not specified. It doesn#t mean that the data can't base on ObjectJc, but the access is not able via this reflection definition. It may or may not based on any superclass. Use the macro CONST_xxx_ClassJc instead if you have complexer structures.

It is been designated for a whole reflection constant definition block with the following rules:

  • The name of the constant whole reflection instance should be reflectionNAME.

  • The virtual table is denoted with vtbl.

  • The attribute-block is denoted with fields.

  • A superclass or any interfaces are not present.

  • Methods are not present.

  • SNAME -

  • NAME -


UML=/Package[ReflectionJc_h]/Namespace.ownedElement[]/Class[FieldJc]

Class FieldJc im Package ReflectionJc_h

UML=/Package[ReflectionJc_h]/Namespace.ownedElement[]/Class[FieldJc]

A field is one entry in the reflection information about attributes or references of any type. In opposite to orignal-Java a FieldJc is not based on Object, but the Field[]-type, in Jc named "FieldJcArray" is based on ObjectJc like every ARRAYJc. It means at ex you cannot call toString_ObjectJc(myField.object), it results in a compiler syntax error. The reason if the FieldJc-type do not based on ObjectJc is: preserve of expenditure, it is not necessary. A field may describe:

but the Java2C translator produces such constructs because optimization, and a hand write code

can use this because optimization. The type field references to ;;ReflectionEmbeddedType,

but the modifier-bit mEmbedded_Modifier_reflectJc is set in bitModifiers.

Attributes:

+-------'-------'-------'-------'-------'-------'-------'--...30+
|                             name                              |
+-------'-------'-------'-------'-------'-------'-------'-------+
|                 nrofArrayElementsOrBitfield_                  |
+-------'-------'-------'-------+-------'-------'-------'-------+
|            type_              |         bitModifiers          |
+-------'-------+-------'-------+-------'-------'-------'-------+
|   position    |offsetToObjectifcBase|        declaringClass         |
+-------'-------'-------'-------'-------'-------'-------'-------
Pos. 0x0..0x1D = 0..29 ( 30 bytes): name : char [30]

The symbolic name of the field

Pos. 0x1..0x = 1..NaN ( NaN bytes): nrofArrayElementsOrBitfield_ : u_int16_t

Size of the field or size of 1 element if it is an static array.

Pos. 0x..0x = NaN..NaN ( NaN bytes): type_ : ClassJc

The class object representing the type of the field. It may be a class object also for primitive types or for primitive Type there is a simple constant value, see REFLECTION_type above.

Pos. 0x..0x = NaN..NaN ( 4 bytes): bitModifiers : int32

The modifiers of the Field. The Bits are defined in Modifier_reflectJc. The concept follows Java, see java.lang.reflect.Field.getModifier or java.lang.reflect.Modifier, but it is enhanced in respect to C/C++ and UML requirements.

Pos. 0x..0x = NaN..NaN ( 2 bytes): position : int16

position of the field inside a object of the type of the declaring class. The position is the offset from the ObjectJc base class to the field, not the offset from the total base. Because it is possible that the object is known via interface reference. A interface reference pointered the position of the pointer to the virtual table of the interface, a call of obj->toObjectJc() is necessary to get the base for this offset.

Pos. 0x..0x = NaN..NaN ( 2 bytes): offsetToObjectifcBase : int16

Offset in a pointered class to the ObjectifcBaseJcpp class structure if such base interface exists. This value is 0 if it is not a pointer or if it is a pointer of not Object-derivated structures.

Pos. 0x..0x = NaN..NaN ( NaN bytes): declaringClass : ClassJc

The class object representing the class or interface that declares the field represented by this Field object.

Methoden:

const_FieldJc (SNAME, NAME, TYPE, MODI) :
  • SNAME: -

  • NAME: -

  • TYPE: -

  • MODI: -

  • returns: -

const_ObjectJcpp_FieldJc (SNAME, NAME, TYPE) :
  • SNAME: -

  • NAME: -

  • TYPE: -

  • returns: -

getName_FieldJc (THIS) :
  • THIS: -

  • returns: -

ctorM_FieldJc (rawMem) : FieldJc

initializes a FieldJc, see ctorc_FieldJc(...).

  • rawMem: MemC - raw memory area, it may be uninitialized. The size may be greater as necessary. The constructor initializes only its own area.

  • returns: FieldJc -

  • throws - IllegalArgumentException if the sizeof rawMem is to less.

ctorc_FieldJc (ythis) : void

initializes a FieldJc. All content is set to 0.

  • returns: void -

getType_FieldJc (ythis) :
  • returns: -

getDeclaringClass_FieldJc (THIS) :
  • THIS: -

  • returns: -

getModifiers_FieldJc (THIS) :
  • THIS: -

  • returns: -

getStaticArraySize_FieldJc (THIS) :
  • THIS: -

  • returns: -

getMemoryAddress_FieldJc (ythis, instance, bFieldAddr, sVaargs, vaargs) : MemSegmJc

Gets the absolute adress of the element represented by this field inside the given Instance. It is assumed, that the instance matches to the Field ythis, it means, the Field ythis is getted from a instance of exactly this type or from the instance itself. This is tested by original Java - set- or get- operations. But it is not tested here to optimize calculation time. If it is a part of a Java2C-translation, the test should be done on Java-level, if it is a directly programmed in C or C++ part, the user should be programmed carefully, how it is ordinary in C or C++.

Simple field, also if the field is a reference type: intance-->[ ...some fields] [ ... ] [ this field----]<--<<This reference will be returned. [ ... ]

Embedded-array-field, also if the field-elements are a reference types: intance-->[ ...some fields ] [ ... ] [ [this field is] ] [ [an aarry ....] ] [ [..element<---]-]--<<This reference will be returned. [ [..element ] ] [ ... ]

If the field references an array, the address of the field itself is returned.

  • instance: MemSegmJc - the Object. It need not derivated from ObjectJc, it may be any struct or class, but the type should matched to the ClassJc description getted with getDeclaringClass_FieldJc(ythis).

  • bFieldAddr: bool - If it is true, then instance contains the address of the field already. This method is then used only to calculate the address of an element inside the array, if it this is an array-kind-element. This functionality is used internally.

  • sVaargs: char - The method can have one or more indices to index an element in the array, if ythis is an array-field. The sVaarg-string contains one or more characters "I" to designate that the following variable arguments are from type int. This concept of processing a variable argument list is established with the Java2C-translator. In Java the type of the elements of a variable argument list are well known in Runtime, other than its usual in C. This String defines the types. It the type is null or empty, no variable arguments are given.

  • vaargs: va_list - indices for indexing an array element.

  • returns: MemSegmJc - The address of the field or the address of a element inside the array-kind-field with the given indices. Note: To get the address of elements of a container field, use >getAddrElement_FieldJc(...)

getContainerAddress_FieldJc (ythis, instance, sVaargs, vaargs) : MemSegmJc

Gets the absolute adress of the container represented by this field inside obj. It is assumed that the obj represented that object, which contains really this field. Otherwise the behavior is undefined.

At example: If a field references an int[]-Array (at ex int32Array-Typ in ObjectJc.h), this method returns the address of the whole array instance.

The container contains the reference. The container may be referenced too. A simplest container is a simple reference, than the container is embedded. A more complex container may be an ObjectArrayJc, or some UML-Containers. It may be embedded or not.

Variant if the container is referenced: intance-->[ ...some fields] [ ... ] [ this field----]--+-->[container....] [ ... ] | [ refOfData--]-->[the data]

+--<<This reference will be returned.

Variant if the container is embedded in the intstance: intance-->[ ...some fields ] [ ... ]

+---->[ [this field is] ]

[ [a container..] ]

[ [refOfData----]-]-->[the data]

[ ... ]

+--<<This reference will be returned.

See method >getAddrElement_FieldJc(...), this methods accesses inside the container with a given index.

  • instance: MemSegmJc - the Object. It shouln't derivated from ObjectJc, it may be any struct or class, but the type should matched to the ClassJc description getted with getDeclaringClass_FieldJc(ythis).

  • sVaargs: char - The method can have one or more indices to index an element in the array, if ythis is an array-field. The sVaarg-string contains one or more characters "I" to designate that the following variable arguments are from type int. This concept of processing a variable argument list is established with the Java2C-translator. In Java the type of the elements of a variable argument list are well known in Runtime, other than its usual in C. This String defines the types. It the type is null or empty, no variable arguments are given.

  • vaargs: va_list - indices for indexing an array element.

  • returns: MemSegmJc - if the container is an embedded element, this method returns the same value as getMemoryAddress_FieldJc(...), but if it is referenced, the referenced address is returned. The bits mContainerReference_Modifier_reflectJc in bitModifiers are tested to get the result.

getAddrElement_FieldJc (ythis, instance, sVaargs, vaargs) : MemSegmJc

Gets the address of the element described with the field of the given object. It regards whether the field is of container type, it regards the index.

  • instance: MemSegmJc -

  • sVaargs: char - The method can have one or more indices to index an element in the array, if ythis is an array-field. The sVaarg-string contains one or more characters "I" to designate that the following variable arguments are from type int. This concept of processing a variable argument list is established with the Java2C-translator. In Java the type of the elements of a variable argument list are well known in Runtime, other than its usual in C. This String defines the types. It the type is null or empty, no variable arguments are given.

  • vaargs: va_list - indices for indexing an array element.

  • returns: MemSegmJc - s the address of the reference maybe in a container or the address of the reference immediately, if it isn't a container. If the contained instances in the container are embedded in the container, this address is equal with the address of the instance. If the instances in the container are references, this is the address where the reference to the instance is found. The type of the reference should be regarded. Check (getModifiers_FieldJc(field) & mAddressing_Modifier_reflectJc) to detect which to do whith the address.

  • throws - IndexOutOfBoundsException if the idx is fault.

  • since - 2009-11-26, it is necessary to set references with the inspector-Tool.

getRefAddrUML_LinkedList_FieldJc (container, sVaargs, vaargs, _thCxt) : MemSegmJc

Gets the absolute address of the indexed element of a UML-specific container element known as UML_LinkedList. The algorithm should be specified in the users area (extra file.c) because it is UML-Framework-specific.

  • container: MemSegmJc -

  • sVaargs: char -

  • vaargs: va_list -

  • returns: MemSegmJc -

  • throws - IndexOutOfBoundsException if the idx is fault.

getRefAddrUML_ArrayList_FieldJc (container, sVaargs, vaargs, _thCxt) : MemSegmJc

Gets the absolute address of the indexed element of a UML-specific container element known as UML_ArrayList. The algorithm should be specified in the users area (extra file.c) because it is UML-Framework-specific.

  • container: MemSegmJc -

  • sVaargs: char -

  • vaargs: va_list -

  • returns: MemSegmJc -

  • throws - IndexOutOfBoundsException if the idx is fault.

getRefAddrUML_Map_FieldJc (container, sVaargs, vaargs, _thCxt) : MemSegmJc

Gets the absolute address of the indexed element of a UML-specific container element known as UML_Map. The algorithm should be specified in the users area (extra file.c) because it is UML-Framework-specific.

  • container: MemSegmJc -

  • sVaargs: char -

  • vaargs: va_list -

  • returns: MemSegmJc -

  • throws - IndexOutOfBoundsException if the idx is fault.

get_FieldJc (ythis, instance, sVaArgIdx) : MemSegmJc

Gets the object represented by the Field ythis from an given object. If it is not a complex datatype but an simple type (int, float and others), this method returns null. This is in opposite to Java, java wrappes the primitive type.

If the object it is a C++ class and it is derived from ObjectJc, this method returns the pointer to the baseclass ObjectJc of the instance. If the instance itself with its really type should be gotten, a <dynamic_cast>(ptr) is necessary, usual in C++.

If the object isn't based on ObjectJc, the address of that entry in the instance is returned, which is matching to the type of the field. It means, if multi-inheritance is used in C++, it may not be the really address of the instance. Than a dynamic_cast from the known pointer with the correct type to the type of the instance supplies the really instance-address. The type of the instance isn't able to evaluate with reflection in this case, it should be known by the programmer.

If the object is located in an external memory, the reference in that memory with the adequate segment information is returned.

  • instance: MemSegmJc -

  • sVaArgIdx: char -

  • returns: MemSegmJc -

get_FieldJc (ythis, obj, idx) : MemSegmJc
  • obj: ObjectifcBaseJcpp -

  • idx: int -

  • returns: MemSegmJc -

searchObject_ClassJc (sPath, startObj, field, idx) : MemSegmJc

Searches an object with given start object and path. This is a static method in context of ClassJc. The returned object may be based on ObjectJc or not. In C/C++ systems, especially in user oriented data structures, the inheritance of ObjectJc is not taken for granted. In this cases the describing ClassJc information will be kept as getType_FieldJc() in the Field information of this element, not in the implementing instance.

  • sPath: StringJc - The path to the object. At example "myObj.theElement[20].x".

  • startObj: ObjectJc - The object from which the path starts, it have to be based on ObjectJc.

  • field: FieldJc - Reference to a FieldJc reference, it will be set as return with the last found Field information.

  • idx: int - Reference to a int, it will be set as return with the last found index information in path, or set to -1 if no index is given at last position.

  • returns: MemSegmJc - The founded object matching to the returned field. The Object is the last but one part of the VariablePath, but the returned field is the last part of the Variable path. The returned idx is >=0 if the last part contains an index information.

getObjAndClass_FieldJc (ythis, instance, retClazz, sVaargs) : MemSegmJc

Gets the Object and the describing class of the Object from given FieldJc in given object. See get_FieldJc(...) If the object is non based on ObjectJc, it hasn't own reflection infos inside it, but the reflection info to the pointer to it is known as a Class type, returned by getType_FieldJc. In this case this information is supplied. The class info always matches to the returned obj. If the field describes a primitive type, it returns null and sets obj to null.

  • instance: MemSegmJc -

  • retClazz: -

  • sVaargs: char -

  • returns: MemSegmJc -

getArraylength_FieldJc (ythis, instance) : int

Gets the actual length of the array if the field describes a reference of an array or collection,

  • instance: MemSegmJc -

  • returns: int - the actual length, it may be 0.

  • throws - NoSuchFieldException if it describes not an array or collection.

getArraylengthUML_LinkedList_FieldJc (instance) : int
  • instance: MemSegmJc -

  • returns: int -

getArraylengthUML_ArrayList_FieldJc (instance) : int
  • instance: MemSegmJc -

  • returns: int -

getArraylengthUML_Map_FieldJc (instance) : int
  • instance: MemSegmJc -

  • returns: int -

getBoolean_FieldJc (ythis, instance, sVaargs) : bool
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: bool -

getChar_FieldJc (ythis, instance, sVaargs) : char
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: char -

getByte_FieldJc (ythis, instance, sVaargs) : int8
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: int8 -

getShort_FieldJc (ythis, instance, sVaargs) : int16
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: int16 -

getInt_FieldJc (ythis, instance, sVaargs) : int32
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: int32 -

getBitfield_FieldJc (ythis, instance, sVaargs) : int16

Set the bits of a bitfield descibed by the given field.

  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: int16 - The value for the bits. The bits are adjusted rigth here, they will be shifted from the correct bit position. NOTE: It is a int-value, may be 16 bit, because the register width is proper for that.

  • javalike - : Because java doesn' know bitfields, it isn't java-like, but it is proper and necessary for C-programming.

getFloat_FieldJc (ythis, instance, sVaargs) : float
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: float -

getDouble_FieldJc (ythis, instance, sVaargs) : double
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: double -

getString_FieldJc (ythis, instance, sVaargs) : StringJc

Gets a String representation of the content of this FieldJc in the given instance. <ul> <li>If the field is a Object-compatible type (a reference) and the reference is not null, then the Object.toString()-method is invoked with this reference. <li>If the reference is null, than "null" is returned. <li>If the field is a primitive type, the String representation of its content is returned. <li>For C-usage: If the field references a non-Object-instance, "

  • instance: MemSegmJc - The instance where this FieldJc is member of.

  • sVaargs: char -

  • returns: StringJc - A String which represents the content of the field.

  • addr - " is returned, where addr is the memory address of the referenced instance (the reference value). </ul>

  • throws - IllegalArgumentException

  • throws - IllegalAccessException

getReference_FieldJc (ythis, instance, sVaargs) : MemSegmJc

Returns the reference to the field inside the given object. This method is not javalike. Because the type of the field is not known in this context, the reference is of type void*. The user should cast it outside to the type of the field. The casting is only admissible to the exactly type of the field. If it is a primitive type, the reference may be casted to the reference to the primitive type, such as (int*). If the reference is a complex type, especially a interface in C++, the cast is only admissible to the interface type, not to a supposed derivated type. The casting to a derivated type in C++ is only admissible with static_cast<type>, because the compiler should adjust the reference.

  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: MemSegmJc -

  • since - 2010-07-01: Uses anyway, returns the address of the container or primitive type, if it isn't a reference, returns the reference to the instance if it is a reference.

getReference_V_FieldJc (ythis, instance, sVaargs, vaargs) : MemSegmJc
  • instance: MemSegmJc -

  • sVaargs: char -

  • vaargs: va_list -

  • returns: MemSegmJc -

getMemoryIdent_FieldJc (ythis, instance, sVaargs) : int32
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: int32 -

getMemoryIdent_V_FieldJc (ythis, instance, sVaargs, vaargs) : int32
  • instance: MemSegmJc -

  • sVaargs: char -

  • vaargs: va_list -

  • returns: int32 -

getInt64_FieldJc (ythis, instance, sVaargs) : int64
  • instance: MemSegmJc -

  • sVaargs: char -

  • returns: int64 -

setBoolean_FieldJc (ythis, obj, val, sVaargs) : bool
  • obj: MemSegmJc -

  • val: bool -

  • sVaargs: char -

  • returns: bool -

setChar_FieldJc (ythis, obj, val, sVaargs) : char
  • obj: MemSegmJc -

  • val: char -

  • sVaargs: char -

  • returns: char -

setByte_FieldJc (ythis, obj, val, sVaargs) : int8
  • obj: MemSegmJc -

  • val: int8 -

  • sVaargs: char -

  • returns: int8 -

setShort_FieldJc (ythis, obj, val, sVaargs) : int16
  • obj: MemSegmJc -

  • val: int16 -

  • sVaargs: char -

  • returns: int16 -

setInt_FieldJc (ythis, instance, val, sVaargs) : int32
  • instance: MemSegmJc -

  • val: int -

  • sVaargs: char -

  • returns: int32 -

setLong_FieldJc (ythis, obj, val, sVaargs) : int64
  • obj: MemSegmJc -

  • val: int64 -

  • sVaargs: char -

  • returns: int64 -

setBitfield_FieldJc (ythis, obj, val, sVaargs) : int

Set the bits of a bitfield descibed by the given field.

  • obj: MemSegmJc - The object to set the value inside.

  • val: int - The value for the bits. The bits are adjusted rigth here, they will be shifted to the correct bit position. NOTE: It is a int-value, may be 16 bit, because the register width is proper for that.

  • sVaargs: char -

  • returns: int -

  • javalike - : Because java doesn' know bitfields, it isn't java-like, but it is proper and necessary for C-programming.

setFloat_FieldJc (ythis, instance, val, sVaargs) : float
  • instance: MemSegmJc -

  • val: float -

  • sVaargs: char -

  • returns: float -

setDouble_FieldJc (ythis, obj, val, sVaargs) : double
  • obj: MemSegmJc -

  • val: double -

  • sVaargs: char -

  • returns: double -

setReference_FieldJc (ythis, instance, value, sVaargs) : void

Sets a reference at the desired field in the given object obj. The field should be a reference type of a scalar or not object-based instance. In other cases (if it is a scalar direct or a object base reference), the method throws IllegalArgumentException. Use set_FieldJc to assign a reference to a object-based instance. The method don't check anything. This method isn't exist in java, because java don't know references.to not object base instances.

  • instance: MemSegmJc -

  • value: void - The reference to the destination instance to set in the object's field.

  • sVaargs: char -

  • returns: void -

  • exception - IllegalArgumentException if the methode doesn't match to the arguments.

new_FieldJcArray (size) :
  • size: int -

  • returns: -

CONST-Initializer:

CONST-Initializer sind Makros für C-Konstanten, sie sind in Headerfiles definiert. C-Konstante sind Konstrukte in { ... } mit ausschließlich konstanten Werten. Die Makros der CONST-Initializer übernehmen Argumente, die zur Compilezeit die Konstanten bestimmen. Die Initializer sind deshalb als Makros definiert, weil die Struktur der Konstanten exakt der struct-Definition folgen muss, die struct ist im Headerfile definiert, daher auch dazu passend diese Makros. Mit denCONST-Intializer ist es auf einfache Weise möglich, C-struct-Daten (Plain Old Data) zu initialisieren. Für Klassen (C++) ist dieses Konzept nicht geeignet.

CONST_ARRAYFIELDJc(SNAME, NAME, TYPE, MODI)

Defines the constant value of a field instance. The followed defines have to be defined before:

  • REFLECTION_CURRENTJc

  • SNAME -

  • NAME -

  • TYPE -

  • MODI -

CONST_ARRAYHEAD_FieldJc(NAME)

Macro for a constant head of FieldJc array useable to define the constants for reflection. New since 2007.09

  • NAME -

CONST_ARRAYHEAD_z_FieldJc(SIZE, OWNADDRESS)

Macro for a constant head of FieldJc array useable to define the constants for reflection. New since 2007.09

  • SIZE -

  • OWNADDRESS -

CONST_FIELDJc(SNAME, OFFSET, TYPE, MODI)

Defines a field as constant structure.

  • SNAME - name of field element as string literal.

  • OFFSET -

  • TYPE - type of the name, with Reflection_NAME the associated classJc is designated.

  • MODI - Mofifier, using values of enum type Modifier_reflectJc_t.

CONST_FieldJc(CLASS, SNAME, NAME, TYPE, MODI)

Constant Definition of a FieldJc-instance inside a whole reflection definition.

  • CLASS - Name of the Type wherein this field is defined. The Value is used to calculate the offset of the element and to build the pointer to the declaring class in Form reflection##CLASS.clazz.

  • SNAME - String given name of the field. It should be identical with NAME, but with quotion marks.

  • NAME - identifier of the element inside the Type CLASS.

  • TYPE - The type of the the element, the reflection class is build with reflection##TYPE

  • MODI - Modifier, see CLASS_C ModifierJc.


UML=/Package[ReflectionJc_h]/Namespace.ownedElement[]/Class[MethodJc]

Class MethodJc im Package ReflectionJc_h

UML=/Package[ReflectionJc_h]/Namespace.ownedElement[]/Class[MethodJc]

Attributes:

+-------'-------'-------'-------'-------'-------'-------'--...32+
|                             name                              |
+-------'-------'-------'-------+-------'-------'-------'--...8+
|          bModifiers           |            adress             |
+-------'-------'-------'-------'-------'-------'-------'-------+
|                            eType                              |
+-------'-------'-------'-------'-------'-------'-------'-------
Pos. 0x0..0x1F = 0..31 ( 32 bytes): name : char [32]
Pos. 0x1..0x4 = 1..4 ( 4 bytes): bModifiers : int32

Modifier see java class Modifier

Pos. 0x5..0x = 5..NaN ( NaN bytes): adress : Object__VoidMethod

adress of the method

Pos. 0x..0x = NaN..NaN ( NaN bytes): eType : Type_MethodJc

Type of the method

Methoden:

getName_Method (ythis) : StringJc
  • returns: StringJc -

invoke_v_MethodJc (ythis, instance, params) : int32

Invokes the underlying method represented by this Method object, on the specified object with the specified parameters. Individual parameters are automatically unwrapped to match primitive formal parameters, and both primitive and reference parameters are subject to method invocation conversions as necessary. <br/>

If the underlying method is static, then the specified obj argument is ignored. It may be null. <br/>

If the number of formal parameters required by the underlying method is 0, the supplied args array may be of length 0 or null. <br/>

If the underlying method is an instance method, it is invoked using dynamic method lookup.<br/>

  • instance: MemSegmJc -

  • params: -

  • returns: int32 -

invoke_MethodJc (ythis, obj, params) : int32
  • obj: ObjectJc -

  • params: -

  • returns: int32 -

get_MethodJcARRAY (ythis, idx) : MethodJc
ptrConstCasting_MethodJcARRAY (ptr) :

Converts a Array of type MethodJcARRAY with any desired size to the given MethodJcARRAY-Type. The conversion may test the content or not.

  • ptr: ObjectArrayJc -

  • returns: -

CONST-Initializer:

CONST-Initializer sind Makros für C-Konstanten, sie sind in Headerfiles definiert. C-Konstante sind Konstrukte in { ... } mit ausschließlich konstanten Werten. Die Makros der CONST-Initializer übernehmen Argumente, die zur Compilezeit die Konstanten bestimmen. Die Initializer sind deshalb als Makros definiert, weil die Struktur der Konstanten exakt der struct-Definition folgen muss, die struct ist im Headerfile definiert, daher auch dazu passend diese Makros. Mit denCONST-Intializer ist es auf einfache Weise möglich, C-struct-Daten (Plain Old Data) zu initialisieren. Für Klassen (C++) ist dieses Konzept nicht geeignet.

CONST_ARRAYHEAD_MethodJc(NAME)
  • NAME -

CONST_MethodJc(CLASS, SNAME, NAME, TYPE, MODI)
  • CLASS -

  • SNAME -

  • NAME -

  • TYPE -

  • MODI -