Ein toller Tag ;-)

... soooo schön ...

Einfach nur schön ;-)

... mit meiner Isa ...

Amrum ...

... ein wahrer Traum ;-)

Mickel in Urlaub ;-)

... soooo eine tolle Erfahrung!

Sonntag, 29. Oktober 2017

Fraenzi Hamburg

Fränzi Hamburg - vegetarisch und vegan

https://fraenzi-hh.de

Adresse:

Lange Reihe 93
20099 Hamburg
040 24859394

... scheint echt cool zu sein ;-)

Öffnungszeiten:

Sonntag Geschlossen
Montag 08:00–22:00
Dienstag 08:00–22:00
Mittwoch 08:00–22:00
Donnerstag 08:00–22:00
Freitag 08:00–22:00
Samstag 12:00–22:00

Share:

Glashaus Restaurant Lueneburg

Glashaus Restaurant Lüneburg

http://glashaus-restaurant.net

https://www.facebook.com/glashausrestaurant

... Restaurant - Burger - events ...

Speisekarte:

  • Burger
  • Currywurst
  • ganz selten: Steak
  • ... aber wirklich gut ;-)

Öffnungszeiten:
Samstag Ruhetag
Mo & Di Abend geschlossen

Adresse:
Bessemerstraße 3
21339 Lüneburg
04131 7773762


Share:

Kurzurlaub - eine interessante Idee

Kurzurlaub - eine interessante Idee;-)

https://www.kurzurlaub.de

... dort gibt es durchaus mal wieder Schnäppchen ;-)
... mal stöbern ...
Share:

Vitamin B17 - eine Krebstherapie?

Vitamin B17 - eine Krebstherapie?

http://www.naturheilmagazin.de/natuerlich-heilen/krankheiten-a-bis-z/krebs/vitamin-b17-therapie.html

Blausäuere , Mandel , Mandeln mandel mandeln

Vitamin B17 in der Geschichte der Krebstherapie

Vitamin B17 blickt auf eine lange, äußerst wechselhafte Geschichte in der Krebstherapie zurück. Der Bitterstoff, der auch als Amygdalin bekannt ist, wurde erstmals von Campbell und Haworth im Jahr 1924 synthetisiert.
In der Krebstherapie kam es erstmals 1845 in Russland zum Einsatz, in den USA dann in den 1920er Jahren – damals noch als Tabletten.
In den 1950er-Jahren wurden die Forschungen wesentlich von Dr. Ernst T. Krebs vorangetrieben, der den Namen Vitamin B17 vergab. [Heute geht man davon aus, dass Amygdalin gar kein Vitamin ist, weil es für den gesunden Menschen nicht essentiell ist, weshalb man besser von Amygdalin spricht. Anm. d. Red.]. Schließlich wurde Amygdalin als halbsynthetisches Präparat zur Infusion unter dem Namen Laetrile (Lätril) patentiert.
In den folgenden Jahren wurde Laetril mit steigender Nachfrage in der Krebstherapie eingesetzt. Einen regelrechten Boom gab es in den 1970er-Jahren, in denen Laetrile nicht nur in den USA, sondern auch in Deutschland in der Krebstherapie genutzt wurde. Aus dieser Zeit stammen auch die Forschungen von Dr. K. Sugiura (vom Krebsforschungszentrum Sloan Kettering Memorial Hospital, New York) am Tierkrebsmodell. Er kam zu dem Schluss, dass Amygdalin

  • das Tumorwachstum einschränkt
  • die Metastasierung verhindert
  • Schmerzen lindert
  • vorbeugend gegen Krebs wirkt
  • das Allgemeinbefinden von Krebspatienten mit verbessern kann.

Etwa zur gleichen Zeit nutzte der Arzt Dr. Hans Nieper in Deutschland Laetrile in großem Stil bei Krebs. Patienten aus aller Welt strömten in die damals weltweit größte Laetrile-Praxis in Hannover. Auch in den USA war Nieper bekannt. Hier setzte sich der Mitgründer der Deutschen Gesellschaft für Onkologie maßgeblich für die Krebstherapie mit Laetrile ein.
Trotz alledem konnte sich Amygdalin nicht durchsetzen. Immer wieder wurde sein Giftigkeit diskutiert, seine Wirksamkeit angezweifelt. In Deutschland gibt es heute kein allgemein zugelassenes Arzneimittel mehr mit Amygdalin. Als Nahrungsergänzungsmittel ist es in der EU erlaubt.
Dennoch gibt es immer wieder Studien, die sich mit der krebshemmenden Wirkung von Amygdalin beschäftigen. Eine Studie kam z.B. zu dem Ergebnis, dass Amygdalin den programmierten Zelltod (Apoptose) von Prostatakrebszellen fördert und daher möglicherweise bei Prostatakrebs wirksam sein könnte [Chang et al., 2006]. Durchgeführt wurden die Versuche an Zellkulturen menschlicher Krebszellen.
Darüber hinaus gibt es vielversprechende Labor- und Tierversuche mit Tumorzelllinien (z.B. Haut, Sarkom, Leukämie, Brustkrebs). Doch nach wie vor fehlen belastbare Studien an Menschen, die die Wirksamkeit von Amygdalin bei Krebs ausreichend belegen. In einem Überblick aus dem Jahr 2016 bescheinigt das amerikanische National Cancer Institut Vitamin B17 zwar eine gewisse Wirkung in Tierversuchen, die Wirkung am Menschen sei aber nicht belegt.

... (siehe Link oben)
Share:

Samstag, 28. Oktober 2017

IQpure - das neue Wasser ;-)

IQpure - das neue Wasser ;-)

http://www.iqpure.de

Share:

Dorfgemeinschaft Dachtmissen

Dorfgemeinschaft Dachtmissen

https://dorfgemeinschaft-dachtmissen.de

... eine tolle Truppe ;-)

Märchenhafter Laternenumzug

Der Laternenumzug durch Dachtmisser Feld und Flur findet dieses Jahr am 27.10. statt. Ab 18.00 Uhr sind wir für Euch da. Der Umzug startet ab 18.30 Uhr. Hinterher freuen wir uns auf einen Plausch mit Euch!

Auto-Anreisende bitte ein paar Minuten mehr und 1.- € einplanen. Der Ort ist aus Sicherheitsgründen für´s Parken gesperrt. Der Parkplatz ist ausgeschildert, die Feuerwehr Reppenstedt weist ein.

Viel Spaß!

und: Laßt Euch überraschen….

( St Sankt Martinsumzug )
Share:

Mittwoch, 25. Oktober 2017

theater im e.novum

theater im e.novum

http://www.theater-enovum-lueneburg.de

Programm & Karten

http://www.theater-enovum-lueneburg.de/kalender.php

Angewandtes Theater, das bewegt!


Das theater im e.novum ist zugleich Theaterschule und Aufführungsort für Eigenproduktionen und Gastspiele. Ziel unserer Theaterschule ist die Verwirklichung eines jungen, kreativen Theaters, in dem das physische Spiel des Schauspielers gegenwärtig ist.

Theater ist mehr als ein Auswendiglernen von Dialogen. Theater lebt von Fantasie, Kreativität und Improvisation. Theater trägt zur Persönlichkeitsentwicklung bei, fördert die soziale Kompetenz und die Konzentration. Wenn man in gemeinsamer Arbeit ein Stück auf die Bühne stellt, lässt man sich aufeinander ein, überschreitet Grenzen und entdeckt neue Welten. Jugendliche und Kinder brauchen für die Bewältigung ihres Alltags Fähigkeiten, die weniger mit Wissen als vielmehr mit Lebenskunst zu tun haben. Sie brauchen Gewissheit über die eigenen Stärken, Mut die Dinge kritisch zu beobachten, Vertrauen in die eigene Kraft und die Bereitschaft, Verantwortung zu übernehmen für sich und andere. Kreativität, soziales Interesse, Verantwortungsbereitschaft und Selbstbewusstsein werden beim Theater spielen gefördert.

“Wenn die Kinder sagen, dass sie Spaß haben wollen, muss ich sie fragen, was sie unter Spaß verstehen. Denn sie sind an Ablenkung gewöhnt. Das ist aber nicht von Bedeutung. Was ich meine, ist Freude und Zufriedenheit, und die entsteht nur, indem man für seine Ziele kämpft.”  (Royston Maldoom)

Deshalb machen wir Theater! Mit großem Herzen und großer Freude!

Margit Weihe, Theaterleitung
Share:

Montag, 23. Oktober 2017

Ausbreitung von Demenz: Immer mehr junge Menschen betroffen

Ausbreitung von Demenz: Immer mehr junge Menschen betroffen


http://www.heilpraxisnet.de/naturheilpraxis/ausbreitung-von-demenz-immer-mehr-juenge-menschen-betroffen-20171021390736

Angehörige von jung an Demenz erkrankten Menschen unterstützen

Zwar trifft die Alzheimer-Krankheit zumeist Menschen ab 65 Jahren, doch bestimmte Demenzformen treten schon ab dem Alter von 50 Jahren auf. Selbst Kinder können erkranken. Meist haben es junge Demenz-Patienten besonders schwer, weil Hilfsangebote noch rar sind. Nun gibt es einen Online Ratgeber zur Demenz im jüngeren Lebensalter.

Zahl der Demenz-Patienten wird sich weiter erhöhen

Der Deutschen Alzheimer Gesellschaft (DAlzG) zufolge leben in Deutschland heute etwa 1,6 Millionen Menschen mit Demenzerkrankungen. Ungefähr 60 Prozent davon leiden an einer Demenz vom Typ Alzheimer. Doch die Zahl steigt immer weiter. Laut den Experten wird sie sich bis 2050 auf drei Millionen erhöhen, sofern kein Durchbruch in der Therapie gelingt. Auch immer mehr junge Menschen sind betroffen. Ein neuer Online Ratgeber unterstützt nun Angehörige von jung an Demenz erkrankten Menschen.


Demenz trifft zwar in erster Linie Senioren, doch auch immer mehr jüngere Menschen sind betroffen. Angehörige von jung an Demenz erkrankten Menschen sind besonders auf Unterstützung angewiesen. Für sie gibt es nun einen neuen Online Ratgeber. (Bild: JSB31/fotolia.com)
Hilfe für Angehörige von Betroffenen

Laut der DAlzG werden rund 80 Prozent aller Demenzkranken hierzulande von ihren Angehörigen versorgt und begleitet. Bei den Helfenden führt das nicht nur zu finanziellen Einbußen, sondern mitunter auch zu gesundheitlichen Problemen.

Pflege ist finanziell, körperlich und psychisch eine starke Belastung. Experten fordern seit langem, dass Angehörige von Demenzpatienten mehr unterstützt werden müssen.

Ein neues Informationsangebot unter „www.ratgeber-junge-demenz.de“ unterstützt Angehörige von jung an Demenz erkrankten Menschen.

Der im Rahmen des europäischen Projekts RHAPSODY entstandene Online Ratgeber steht auf den Internetseiten der DAlzG kostenlos zur Verfügung.

Auch jüngere Menschen erkranken

Demenzen beginnen meist erst im höheren Lebensalter. Wenn ein Mensch aber bereits im berufstätigen Alter an einer Demenz erkrankt, stellt dies die Familie vor ganz besondere Herausforderungen, schreibt die Gesellschaft in einer Mitteilung.

Der Beruf muss aufgegeben werden, Kinder müssen den langsamen Verlust eines Elternteils miterleben und die ganze Lebensplanung wird infrage gestellt.

In dem europäischen Projekt RHAPSODY (Research to Assess Policies and Strategies for Dementia in the Young) wurde ein Online Ratgeber zur Demenz im jüngeren Lebensalter in Form eines E-Learning Angebots in drei Sprachen entwickelt.

Er soll insbesondere Angehörige der Betroffenen dabei unterstützen, das gemeinsame Leben mit der Krankheit zu gestalten. Der Ratgeber informiert zu medizinischen Aspekten, zum Umgang mit den Erkrankten, zu rechtlichen Fragen und Unterstützungsangeboten.

Außerdem unterstützt er Angehörige dabei, mit den Veränderungen in der Beziehung zu den Erkrankten umzugehen und dabei die Sorge für sich selbst nicht zu vergessen.

Multimediales Informationsangebot

„In Deutschland gibt es bisher kaum Informationsangebote zur Demenz im jüngeren Lebensalter“, so Sabine Jansen, Geschäftsführerin der DAlzG.

„Ich freue mich deshalb, dass wir als Partner im Projekt RHAPSODY an der Entwicklung dieses multimedialen Informationsangebots mitwirken konnten, das eine wichtige Lücke schließt“, sagte die Expertin.

„Darüber hinaus braucht es allerdings noch weit mehr Aufmerksamkeit für das Thema und die Entwicklung neuer Unterstützungsangebote, um die Situation von jung an Demenz erkrankten Menschen und ihren Familien zu verbessern.“

Aufklärung über die Krankheit
Experten zufolge erfordere der Umgang und die Kommunikation mit Betroffenen grundsätzlich viel Aufmerksamkeit, Mühe, Ruhe und Geduld.

Man sollte demente Menschen nicht überfordern und Stress möglichst meiden.

Außerdem wird immer wieder darauf hingewiesen, dass man im Umgang mit Demenzpatienten Babysprache vermeiden und Betroffene wie Erwachsene behandeln soll.

Hilfreich ist zudem eine bessere Aufklärung über die Krankheit: Zwar ist Demenz bislang nicht heilbar, sie lässt sich aber im Anfangsstadium mit Medikamenten hinauszögern. Wichtig ist deshalb eine frühzeitige Diagnose.

Doch obwohl Früherkennung einer der wichtigsten Punkte ist, um der Krankheit entgegen zu wirken, wird Demenz oft zu spät erkannt, weil die Warnsignale nicht erkannt werden.

Viele Menschen verbinden mit Demenz den Umstand, sich nicht erinnern zu können, doch auch andere Merkmale können mit der Krankheit einhergehen. Zum Beispiel eine Änderung des Verhaltens oder emotionale Symptome wie Antriebslosigkeit, Aggressivität oder auch Unruhe.

Auslöser von Demenz

Was die genauen Auslöser von Alzheimer sind, ist zwar noch immer unklar, doch von Wissenschaftlern wurden mittlerweile eine Reihe von Faktoren identifiziert, die bei der Entstehung und Entwicklung von Demenz eine Rolle spielen.

Britische Forscher berichteten vor kurzem, dass ein Drittel der Demenz-Fälle verhindert werden könnte, wenn von Kindheit an bestimmte Risikofaktoren eliminiert werden. In einem Beitrag der „BBC“ wurden die neun von den Wissenschaftlern identifizierten Risikofaktoren für Demenz aufgelistet:

Hörverlust im mittleren Lebensalter, mangelnde Bildung im Jugendalter, Rauchen, Depressionen, Bewegungsmangel, soziale Isolation, Bluthochdruck, Adipositas, und Typ 2-Diabetes.

Das persönliche Erkrankungsrisiko könne zwar bis zu einem gewissen Grad beeinflusst werden, doch die Experten räumten ein, dass die Zahlen „mit Vorsicht interpretiert werden“ sollten, da es nicht möglich sei, alle Risikofaktoren komplett zu eliminieren.

Außerdem seien bei den Berechnungen andere potenzielle Risikofaktoren wie z.B. Alkoholkonsum oder Schlafstörungen nicht einbezogen worden. Nicht desto trotz zeige die Studie, dass es möglich sei, gegen die unheilbare Demenz vorzugehen. (ad)
Share:

Samstag, 21. Oktober 2017

Solaranlage fuer die Steckdose

Solaranlage für die Steckdose ;-)


https://www.landeszeitung.de/blog/aktuelles/1160652-die-verbotene-solaranlage

... das ist ja mal echt cool ;-)

Die verbotene Solaranlage

21. Oktober 2017 Hinterlasse einen Kommentar

Lüneburg/Hannover. Die Werbung für die persönliche Energiewende daheim klingt verlockend. „Auspacken. Aufstellen. Einstecken“, heißt es über die Mini-Solaranlagen für Garten oder Balkon. „So einfach kann ein Kraftwerk sein.“ Doch ganz so einfach ist der häusliche Umstieg auf saubere Sonnenenergie dann doch nicht. Die meisten Netzbetreiber sträuben sich noch gegen die neue Art der Stromerzeugung. Das musste nun ausgerechnet auch die Energieexpertin der Grünen-Bundestagsfraktion, Dr. Julia Verlinden, erfahren. Während sie in ihrer Berliner Zweitwohnung bereits ein 150-Watt-Plug-in-Gerät auf ihrem Balkon betreibt, verwehrt ihr die Avacon Netz GmbH die Nutzung im heimischen Lüneburger Garten.

„Leider muss ich Ihnen mitteilen, dass der Anschluss von Einspeiseanlagen an Endstromkreisen zum jetzigen Zeitpunkt nicht gestattet ist“, erteilte ein Avacon-Mitarbeiter unter Verweis auf diverse DIN-Normen Verlinden eine eindeutige Abfuhr. Das will die Kandidatin für die Bundestagswahl nicht so hinnehmen. „Es ist ein Unding, dass ein großer regionaler Netzbetreiber wie die Avacon die Energiewende von unten derart blockiert“, kritisiert die Umweltwissenschaftlerin. „Gerade im Energiewendeland Niedersachsen sollten sich die Netzbetreiber für den Anschluss jedweder Ökostrom-Anlagen stark machen, statt sie zu behindern.“

Mittlerweile sind mehrere Tausend Geräte in Deutschland angeschlossen

In ihrer Antwort an Avacon verweist Julia Verlinden auf eine Studie des Fraunhofer-Instituts von 2016, wonach der Betrieb von modernen, netzgekoppelten Kleinst-Photovoltaik-Anlagen gefahrlos möglich sei. „Das von mir gemeldete Modell ist schon vielfach in anderen Ländern, zum Beispiel in Österreich, in Betrieb.“ Auch in Deutschland seien mittlerweile mehrere Tausend Geräte angeschlossen.

So erlaubt der Dortmunder Betreiber Westnetz, eine ehemalige RWE-Tochter, laut Umweltorganisation Greenpeace seinen Kunden inzwischen grundsätzlich den Einsatz von Balkon-Geräten bis zu einer Grenze von 300 Watt, sofern „Störungen anderer Anschlussnehmer und schädliche Rückwirkungen auf das Stromverteilnetz“ ausgeschlossen seien. Nutzer müssten lediglich Fabrikat, Modell und Leistung melden. Andere Unternehmen müssten diesem unbürokratischen Beispiel schnell folgen, fordert Greenpeace. Doch die meisten Betreiber wie Wesernetz in Bremen winken noch skeptisch ab. Es handle sich um eine meldepflichtige Anlagenerweiterung, die nur ein gelernter Elektroinstallateur ausführen dürfe, sagt ein Sprecher. Bei größeren Einspeisemengen könnten schließlich auch Probleme fürs Netz entstehen.

Modell Simon ist im Internet für rund 600 Euro zu bestellen

Solarmodule wie das Modell Simon zum Aufstellen oder Aufhängen sind im Internet für rund 600 Euro zu bestellen. Man steckt einfach den Stecker in eine Steckdose, der durch Sonnenkraft produzierte Strom wird ins Haus- oder Wohnungsnetz eingespeist. Es wird also weniger Energie von außen benötigt, der eigene Zähler dreht sich langsamer, man spart also Stromkosten. 150 Watt reichen für das Kochen eines Mittagessens oder den ganzjährigen Betrieb einer energieeffizienten Waschmaschine.

Für Verlinden sind auch solch kleine Schritte effektiv. „Jede Kilowattstunde Solarstrom bedeutet am Ende eine weniger aus Kohle und Atom. Das ist gut für die Energiewende und gut für den Klimaschutz.“

Von der Avacon hat Julia Verlinden auch nach Wochen keine Reaktion auf ihre Beschwerde erhalten. Sie sagt: „Ich habe dem Netzbetreiber mittgeteilt, dass ich seine ablehnende Haltung für völlig unbegründet halte. Ich habe meine Mini-Solaranlage daher auch ohne Zustimmung der Avacon in Betrieb genommen.“

Von Peter Mlodoch
Share:

Mittwoch, 18. Oktober 2017

Converting from C prototypes to RPG prototypes

Converting from C prototypes to RPG prototypes

Original:
https://www.ibm.com/developerworks/community/wikis/form/anonymous/api/wiki/097983a0-b012-4248-9d0c-33ef89a6c3dd/page/fc6356ad-a64d-44b5-97cf-3fd47ab479f8/attachment/898b2a00-cc93-4c75-9885-327fafc01d7c/media/Converting_C_Prototypes_To_RPG.html
(as long as this link does work, use this one, as the internal links all work)

© Copyright IBM Corp. 2000, 2013

Converting from C prototypes to RPG prototypes


Introduction

Normally it is quite easy to convert from a C prototype to an RPG prototype. A C prototype has the following form:
     return_type   name  ( parameters );
For example
     double fn (int p1, int p2);  /* function "fn" with 2 4-byte integer */
                                  /* parameters, returning 8-byte float  */
Here is the matching RPG prototype
     D fn           PR        8F   EXTPROC('fn')
     D   p1                  10I 0 VALUE
     D   p2                  10I 0 VALUE
Note:
  • You should already have a basic knowledge of RPG prototypes, and the CONST, VALUE, and OPTIONS keywords.
  • The RPG examples are not formatted in the exact columns.

C scalar types

Easy-to-map scalar types

The mappings for the following list of C scalar types is straightforward
             C               |                RPG
     ------------------------+-----------------------------------
       int x                 |   D   x           10I 0   VALUE
       long x                |   D   x           10I 0   VALUE
       long long x           |   D   x           20I 0   VALUE
       unsigned int x        |   D   x           10U 0   VALUE
       unsigned long x       |   D   x           10U 0   VALUE
       unsigned long long x  |   D   x           20U 0   VALUE
       double x              |   D   x            8F     VALUE
                             |
       short *x              |   D   x            5I 0
       int *x                |   D   x           10I 0
       long *x               |   D   x           10I 0
       long long *x          |   D   x           20I 0
       unsigned short *x     |   D   x            5U 0
       unsigned int *x       |   D   x           10U 0
       unsigned long *x      |   D   x           10U 0
       unsigned long long *x |   D   x           20U 0
       float *x              |   D   x            4F
       double *x             |   D   x            8F

Scalar types that require extra care

There are some scalar types (char, short, unsigned short, float, wchar_t) missing from the top section of the list of easy-to-convert types above.
These seem like they should be straightforward, but they are not. The parameter is coded the same way as the parameter in the bottom section without the VALUE keyword, but you may need to code your EXTPROC keyword differently if you have char, short, or float parameters passed by value or as return values. See C widening.
These scalar types are not always easy to map. Sometimes you may need to code *CWIDEN for your prototype, and sometimes you must read the documentation to determine how to code the parameter or return value in the prototype.
  • character passed by value
         char x
    
    A char passed by value is prototyped in RPG like this.
         D   x             1A    VALUE
    
    See the section on C widening to see if you need to code your EXTPROC in a special way.
  • character passed by reference
         char *x
    
    A char passed by reference could map to a null-terminated string, or to an RPG character string passed by reference. See C string.
  • short, unsigned short, float passed by value
         short s
         unsigned short us
         float f
    
    The RPG parameter definition is coded similar to the way the parameter is code for these types passed by reference, but without the VALUE keyword.
         D   s             5I 0   VALUE
         D   us            5U 0   VALUE
         D   f             4F     VALUE
    
    However, sometimes you may need to code *CWIDEN in your prototype. See C widening.
  • Wide character passed by value
         wchar_t a
    
    This is a double-byte character, most likely Unicode (RPG UCS-2 type), but it could be a specific CCSID, (RPG Graphic type).
  • RPG coding
         D   a            nC   VALUE
    or
         D   a            nG   VALUE
    
    Where "nC" and "nG" means a specific length, for example 25C, 100G etc.You may need to code your EXTPROC keyword in a special way for this parameter type. See the section on C widening.
  • Wide-character passed by reference
         wchar_t *a
    
    The RPG coding is the same as the coding for passing the parameter by value, but without the VALUE keyword.
         D   a            nC
    or
         D   a            nG
    

Complex parameter types


Return values

Return values are coded similar to parameters, with the added point that if a C function has a return value of "void", you just leave out the return type on the RPG prototype.

Arrays

For any parameter that is passed by reference (with * between the type and the name in the C prototype), it is possible that the parameter is supposed to be an array.
In C, type*x can mean "a pointer to the type" or "an array of the type". Usually the documentation for the function will make it clear. Array parameters can also be coded as type name[] (with no numbers between the []).
If you do have an array parameter, you must code it in RPG as the type of the data, with the DIM keyword, and possibly with the CONST keyword, if the parameter is input-only. You must use the documentation to determine the dimension of the array.

Some easy transformations for you to try

Here are a couple of examples of "easy" transformations.Try them yourself before reading the answers.
    1. double sin ( double );

    2. struct s
       {
          int i;
          char c;
       };
       void fn ( float *a, struct s b, struct s *c, unsigned short *d);

Advanced topics


C strings

When you see "char *" in a C prototype, this could mean a few different things:
  1. A pointer to a contiguous array of characters with a pre-determined length. In some cases, it may be well-known to users of the C function that a particular "char *" should be an array of say 10 characters, representing say a blank-filled library name. In RPG, you would prototype such a field with 10A, without the VALUE keyword, and with the CONST keyword if the parameter is input only.
  2. A pointer to a contiguous array of characters whose length is determined by another parameter. You would prototype this in RPG as a character field of some maximum length with OPTIONS(*VARSIZE), without the VALUE keyword, and with the CONST keyword if the parameter is input only.
  3. A null-terminated string. This is a contiguous array of characters whose end is indicated by a null character (x'00'). If this parameter is an input parameter (not changed by the function), you would prototype this as a pointer, with the VALUE keyword, and with OPTIONS(*STRING). If this parameter can be changed by the function, you would prototype it the same way as the previous case (nA OPTIONS(*VARSIZE) where "nA" means some length of character, for example 32767A).

C widening

Problems with "C widening" can occur for these C parameter types, when passed by value:
  • char
  • short
  • unsigned short
  • float
  • wchar_t
Problems can also occur for char and wchar_t return values.
If your return value or any of your parameters is one of these problem types, then you must code your EXTPROC keyword with *CWIDEN, unless there is some indication in the C include that you should code *CNOWIDEN instead.
    D name           PR   EXTPROC(*CWIDEN : 'name').
Use *CWIDEN for prototypes for functions written in C, and also for functions written in RPG, intended to be called by C.
Note: If the C include file specifies #pragma argument(nowiden) for the function, you should use EXTPROC(*CNOWIDEN).
Even though widening is not in effect, coding *CNOWIDEN is still necessary for RPG to handle 1C and 1A correctly, when passed by value or returned.
See the section on C widening background if you are interested in why you have to code *CWIDEN.

Optional parameters

When you see "..." (three dots, called "ellipsis") in a C prototype, it means that there are optional parameters. The number and types of the parameters are normally determined by other parameters. For example, the "printf" function has the following prototype:
int printf(const char *, ...);
The first parameter is a null-terminated string indicating the value to be printed, with replacement variables indicated by %. For example,
printf("%s has %d contracts.", name, number);
says to substitute %s by the first parameter (name) and %d by the second parameter (number). Determining how to pass these parameters, and how to find out what the ellipsis means is beyond the scope of this article. For all functions that have ellipsis in the prototype, you must read the documentation for the function to find out what the optional parameters are.
Sometimes the matching RPG prototype will simply have to code the optional parameters the usual way, adding OPTIONS(*NOPASS). Sometimes, several different RPG prototypes will be needed for every possible call to the function.
Note: If a C prototype has "...", you MUST code OPTIONS(*NOPASS) for at least one parameter, for the other parameters to be passed correctly.

When to use CONST

For any parameter that does not have the VALUE keyword coded, you have the possibility of coding the CONST keyword. Code this keyword when you know the parameter cannot be changed by the function. This is sometimes indicated by the documentation ("input parameter"), and sometimes the C prototype has "const" before the type.
    int fn (const int *i1, int *i2, int i3);
The RPG equivalent:
    D fn           PR           10I 0 EXTPROC('fn')
    D   i1                      10I 0 CONST
    D   i2                      10I 0
    D   i3                      10I 0 VALUE

C named types (typedefs) and structures

To find the actual definition for a named type XYZ, search for code in one of the following forms.
The matching RPG definition for the type is coded with each example.

Renaming of an existing type

     typedef {type} XYZ;
For example
     typedef int XYZ;
RPG coding
     D XYZ_T        S      10I 0   TEMPLATE
This could also be done in RPG as follows, by first defining a template for "int", and then defining another template for XYZ_T:
     D int          S      10i 0   TEMPLATE
     ...
     D XYZ_T        S              LIKE(int) TEMPLATE

Pointer to an existing type

     typedef {type} *XYZ;
For example
     typedef float *ABC_T;
     typedef double* DEF_T;
     typedef SOMETYPE * GHI_T;
Note that the position of the * doesn't matter in the C definition.
RPG coding
     D ABC_T     S        *    TEMPLATE
     D DEF_T     S        *    TEMPLATE
     D GHI_T     S        *    TEMPLATE
Note that since RPG does not have typed pointers, all the RPG definitions are the same.

Struct

A C struct is like an RPG data structure defined using length notation.
     typedef struct
     {
        type1 name1;
        type2 name2;
        ...
     } XYZ;
For example
     typedef struct
     {
        int i;
        double d;
        char name[10];
        char c;
     } S1_T;

     typedef _Packed struct XYZ
     {
        int i;
        double d;
        char name[10];
        char c;
     } S2_T
RPG coding
     D S1_T      DS           ALIGN QUALIFIED TEMPLATE
     D  i               10i 0
     D  d                8f
     D  name            10a
     D  c                1a

     D S2_T      DS           QUALIFIED TEMPLATE
     D  i               10i 0
     D  d                8f
     D  name            10a
     D  c                1a
Note: C structs default to having their subfields aligned. RPG data structures default to not having their subfields aligned.
C uses the _Packed keyword to indicate that subfields should not be aligned, and RPG uses the ALIGN keyword to indicate that subfields should be aligned.
  1. The first C struct does not have the _Packed keyword, so the matching RPG data structure has the ALIGN keyword.
  2. The second C struct has the keyword _Packed, so the RPG data structure does not have the ALIGN keyword.
Warning: Even if you code the ALIGN keyword, your RPG data structure might be a bit smaller than the C version. The C compiler pads out a struct so that its length is a multiple of its alignment. So if the struct contains a pointer, the length will be a multiple of 16.
RPG does not do this, even with the ALIGN keyword, so the RPG data structure might be up to 15 bytes smaller than the C structure. The regex_t struct in qsysinc/h(regex) is an example of this; the C struct is 656 bytes long, but the natural RPG version is only 644 bytes long.
The RPG version of a structure like regex_t should code the data structure length on the DS line of the data structure definition.
     D regex_t      DS        656    ALIGN QUALIFIED TEMPLATE
     D   etc

Union

A C union is like an RPG data structure where all the subfields start at position 1.
     typedef union
     {
        type1 name1;
        type2 name2;
        ...
     } XYZ_t;
For example
     typedef union
     {
        int i;
        double d;
        char name[10];
        char c;
     } XYZ_t;
RPG coding
     D XYZ_t     DS             QUALIFIED TEMPLATE
     D  i               10i 0   overlay(XYZ:1)
     D  d                8f     overlay(XYZ:1)
     D  name            10a     overlay(XYZ:1)
     D  c                1a     overlay(XYZ:1)

Typedef examples

Here are a few examples of typdefs. Try coding the equivalent RPG templates yourself before reading the answers.
    1. typedef int x1;

    2. typedef struct
       {
          int i;
          char c;
          char x[15];
       } x2;

    3. typedef _Packed struct
       {
          int i[5];
          double d;
       } x3;

    4. typedef union
       {
          short s;
          float f;
          double d[2];
       } x4;

    5. typedef x4 *x5;

C equivalent of EXTPROC

When you see a C prototype like
     void fn(void);
you normally assume that the external name for this function is 'fn', so you normally code EXTPROC('fn').
Unfortunately, it is possible that the external name is something other than 'fn'. The way that C specifies that the external name is different is by using #pragma map.
     #pragma map (fn, "fn_v2")

     void fn(void);
The #pragma map says that the function named "fn" should actually be named "fn_v2" externally.
Note:#pragma map can also be used to rename exported data fields.
There is no guarantee that the #pragma map is adjacent to the prototype in the C header file. You should search the entire header file.
You may see more than one #pragma map for the same function. In that case, there will be preprocessor directives to condition which one is in effect. There might also be preprocessor directives conditioning a single #pragma map; in that case, it might be correct to use the original non-mapped name.
You might be able to find out which external name to use from the documentation, or you might be able to guess which one you should use. If you can't determine the right name to use, and if you have access to a C compiler, you can compile a C module using that function, compiling it with whatever compiler options are recommended for that function. Then do DSPMOD DETAIL(*IMPORT) and see what function the C module will call.
See Conditionally picking up one name or the other for information on how to code this in RPG.

Enums (Enumerated types)

A C enum is an integer type, of length 1,2,4 or possibly 8. The enum lists a set of name-constants that have the same type as the enum.
Sometimes, the values for an enum will just be listed in order. In this case, the values are assigned starting with zero. QSY_EIM_CONFIG has the value zero, and QSY_EIM_MASTER has the value 1.
     enum QsyEimConnectSystem
     {
         QSY_EIM_CONFIG,
         QSY_EIM_MASTER
     };
Sometimes, the values for an enum are explicitly assigned.
     typedef enum AcctStatusEnum {
           ACCOUNT_OPEN    = 0,
           ACCOUNT_LOCKED  = 1,
           ACCOUNT_EXPIRED = 2
     } AcctStatusEnum;
Note:The only difference between "typedef enum" and "enum" is that the typedef is referred to by the name at the end of the definition, and the non-typedef is referred to by "enum name". For example, enum AcctStatusEnum above is referred to be the name following the "}" character, AcctStatusEnum. Enum CmpType is referred to be "Enum CmpType".
If the enum does not have a name at all, then it is just a set of named constants, and the type does not matter.
There are two parts to the matching RPG coding, although the second part may not be necessary.
  1. Define named constants for each enum value.
         typedef enum {
             WLMPOL_ENC_UTF16  = 1,
             WLMPOL_ENC_ASCII  = 2,
             WLMPOL_ENC_NATIVE = 3,
             WLMPOL_ENC_UTF8   = 4
         } WlmpolEncoding ;
    
    Matching RPG named constants
         D WLMPOL_ENC_UTF16...
         D                 C             1
         D WLMPOL_ENC_ASCII...
         D                 C             2
         D WLMPOL_ENC_NATIVE...
         D                 C             3
         D WLMPOL_ENC_UTF8...
         D                 C             4
    
  2. Determine the data type that matches the enum.Note: This step is only necessary if the enum is used as a subfield, a parameter, or a return value. If not, then you only need to define the named constants.
    If you see #pragma enum in the C include file, that sets the length for the enum. For example,
         #pragma enum(4)
    or
         #pragma enum(int)
    
    means that the enums have type 4-byte integer.If you see the last value of the enum assigned a very large value, that will set the size of the enum to be an integer that can hold that value. In this case, the name of the final enum value indicates that the enum is intended to be an integer.
         typedef enum
         {
           Qpd_Call_Stack_Counter        = 100,
           Qpd_Suspected_Program         = 101,
           ...
           Qpd_Named_IFS_Object          = 304,
           Qpd_Service_Id                = 400,
           Qpd_Force_to_Integer          = 70000
         } Qpd_Key_t;
    
    If you cannot determine the size of the enum, and you have access to the C compiler, write a program that includes the include file, that prints out the size of the enum.
    Compile the program with CRTBNDC so that it will run in the *NEW activation group, and the printf output will immediately appear on the screen.
         #include 
         #include 
         #include 
         #include 
         main()
         {
            printf ("Size of AcctStatusEnum = %d\n",
                    sizeof(AcctStatusEnum));
         }
    
    It prints "Size of AcctStatusEnum = 1", so you would code it as a 3i. If you have a parameter of type type, passed by value, you would probably need to code *CWIDEN for your prototype. See C widening.
    If you don't have a way to find out the size of the enum, post a question about it on one of the RPG online forums.
Examples of enums converted to RPG with both the named constants and a template defining the data type
  • Example from QSYSINC/H QSYEIMAPI
         #pragma enum(4)
         ...
         enum QsyEimConnectSystem
         {
             QSY_EIM_CONFIG,
             QSY_EIM_MASTER
         };
    
    RPG coding. Since it is not a typedef, I suggest that you add "enum_" to the template name.
          * QSYSINC/H QSYEIMAPI
          *     #pragma enum(4)
          *     enum QsyEimConnectSystem
          *      {
          *         QSY_EIM_CONFIG,
          *         QSY_EIM_MASTER
          *      };
         D enum_QsyEinConnectSystem...
         D              S              10I 0      TEMPLATE
         D  QSY_EIM_CONFIG...
         D              C                      0
         D  QSY_EIM_MASTER...
         D              C                      1
    
  • Example similar to an enum in QSYSINC/H LDAP. The example is altered slightly to show how the name of the enum is not necessarily the same as the typedef name.
         typedef enum account_status {
               ACCOUNT_OPEN    = 0,
               ACCOUNT_LOCKED  = 1,
               ACCOUNT_EXPIRED = 2
         } account_status_t;
    
    The RPG template uses the typedef name.
          * typedef enum account_status {
          *      ACCOUNT_OPEN    = 0,
          *      ACCOUNT_LOCKED  = 1,
          *      ACCOUNT_EXPIRED = 2
          * } account_status_t;
         D account_status_t...
         D              S               3I 0      TEMPLATE
         D  ACCOUNT_OPEN...
         D              C                      0
         D  ACCOUNT_LOCKED...
         D              C                      2
         D  ACCOUNT_EXPIRED...
         D              C                      3
    

Tips

  1. As much as possible, when transforming C definitions and prototypes, keep all the names the same as the C names.
         typedef _Packed struct Qp0l_Scan_Program_Data
         {                                     /*                          */
           char                 userProfile[10]; /* User profile           */
           Qp0l_Scan_Key_t      scanKey;         /* Scan key               */
           Qp0l_Scan_KeySign_t  scanKeySignature;/* Scan key signature     */
         } Qp0l_Scan_Program_Data_t;           /*                          */
    
    Equivalent RPG coding
          * C struct definition is in QSYSINC/H QP0LSCAN
          *   typedef _Packed struct Qp0l_Scan_Program_Data
          *   {
          *     char                 userProfile[10];
          *     Qp0l_Scan_Key_t      scanKey;
          *     Qp0l_Scan_KeySign_t  scanKeySignature;
          *   } Qp0l_Scan_Program_Data_t;
         D Qp0l_Scan_Program_Data_t...
         D                   DS             QUALIFIED TEMPLATE
         D  userProfile               10A
         D  scanKey                         LIKEDS(Qp0l_Scan_Key_t)
         D  scanKeySignature...
         D                                  LIKEDS(Qp0l_Scan_KeySign_t)
    
  2. Be sure to keep track of the source of your information (a C header file in QSYSINC/H, or QSYSINC/MIH, or the C reference manual, etc.). I recommend you keep this right in the source file where you keep your RPG versions. Also, it's a good idea to include the actual C declaration (copy and paste it into your comments).
  3. This discussion does not cover all the things you will see in the C header files. When you come across something you don't understand, post a question to one of the RPG online forums. There will be someone who speaks both C and RPG who will help you.There is an RPG forum in the RPG Cafe on IBM's developerWorks:
  4. You should define your template data structures with the QUALIFIED keyword.If you have a V6R1 or later RPG compiler, you should also define your "typedef" data structures TEMPLATE keyword. Otherwise, you should use the BASED keyword, to base the template data structure on a dummy pointer. If you use the name TEMPLATE for your dummy pointer, it will make it easier to find the definitions later when you can use the V6R1 TEMPLATE keyword.
    Then, to define an actual data structure, or to define a parameter as that data structure, use the LIKEDS keyword.
         typedef struct
         {
            int i;
            char a[10];
         } TTT;
    
         void fn (TTT *t);
    
    Here is the RPG version of the "typedef" and the prototype with some example code calling the function
         D TTT          DS                 ALIGN QUALIFIED
         D                                 TEMPLATE
         D   i                       10I
         D   a                       10A
    
         D myTTT        DS                 LIKEDS(TTT)
    
         D fn           PR                 EXTPROC(*CWIDEN : 'fn')
         D   t                             LIKEDS(TTT)
    
          /free
                myTTT.i = 25;
                myTTT.a = "abcde";
    
                fn (myTTT);
    

Test yourself

Here are a couple of challenging examples. Try them yourself before reading the answers.
    1. /*-----------------------------------------------------*/
       /* fn1                                                 */
       /*-----------------------------------------------------*/
       /* Required parameters:                                */
       /*                                                     */
       /* Input:  p1: null-terminated string                  */
       /* Input:  p2: 10 bytes, right-adjusted, blank filled  */
       /* In:     p3: 1-byte character                        */
       /*                                                     */
       /* Optional parameters:                                */
       /*                                                     */
       /* Input:  p4: int                                     */
       /* Input:  p5: int                                     */
       /*                                                     */
       /* Returns: short int                                  */
       /*-----------------------------------------------------*/
       short fn1 (char *p1, char *p2, char p3, ...)


    2. /*-----------------------------------------------------*/
       /* fn2                                                 */
       /*-----------------------------------------------------*/
       /* Required parameters:                                */
       /*                                                     */
       /* Output: p1: integer                                 */
       /* Input:  p2: array of integers                       */
       /* Input:  p3: array of pointers to character          */
       /*                                                     */
       /* Returns: none                                       */
       /*-----------------------------------------------------*/
       void fn2 (int *p1, int *p2, char *p3[]);



    3. /*-----------------------------------------------------*/
       /* num_recs                                            */
       /*-----------------------------------------------------*/
       /* Required parameters:                                */
       /*                                                     */
       /* Input: filename: 10 bytes, blank-padded             */
       /*                                                     */
       /* Returns: int                                        */
       /*                                                     */
       /* Notes:                                              */
       /* 1.  Compiling with DEFINE(DEBUG) will use a         */
       /*     version of this function that outputs           */
       /*     debugging information to stdout.                */
       /*-----------------------------------------------------*/
       #ifdef DEBUG
         #pragma map(num_recs, "num_recs_debug")
       #endif
       int num_recs (char filename[]);



Answers to easy prototype questions (repeated here)

      1. double sin ( double );

         D sin          PR            8F   EXTPROC('sin')
         D                            8F   VALUE

     2. struct s
        {
           int i;
           char c;
        };
        void fn ( float *a, struct s b, struct s *c, unsigned short *d);


        D s            DS                 ALIGN QUALIFIED TEMPLATE
        D   i                       10I
        D   c                        1A
        D fn           PR                 EXTPROC('fn')
        D   a                        4F
        D   b                             VALUE LIKEDS(s)
        D   c                             LIKEDS(s)
        D   d                        5U 0

Note:EXTPROC(*CWIDEN:'fn') is also correct.

Answers to typedef questions (repeated here)

    1. typedef int x1;

    D x1           PR           10i 0

    2. typedef struct
       {
          int i;
          char c;
          char x[15];
       } x2;

       D x2           DS                 ALIGN QUALIFIED TEMPLATE
       D   i                       10I
       D   c                        1A
       D   x                       15A

    3. typedef _Packed struct
       {
          int i[5];
          double d;
       } x3;

       D x3           DS                 QUALIFIED TEMPLATE
       D   i                       10I   DIM(5)
       D   d                        8F

    4. typedef union
       {
          short s;
          float f;
          double d[2];
       } x4;

       D x4           DS                 QUALIFIED TEMPLATE
       D   s                        5I   DIM(5)
       D   f                        4F
       D   d                        8F   DIM(2)

    5. typedef x4 *x5;

       D x5           S              *   TEMPLATE


Answers to "test yourself" (questions repeated here)

  1.        /*-----------------------------------------------------*/
           /* fn1                                                 */
           /*-----------------------------------------------------*/
           /* Required parameters:                                */
           /*                                                     */
           /* Input:  p1: null-terminated string                  */
           /* Input:  p2: 10 bytes, right-adjusted, blank filled  */
           /* In:     p3: 1-byte character                        */
           /*                                                     */
           /* Optional parameters:                                */
           /*                                                     */
           /* Input:  p4: int                                     */
           /* Input:  p5: int                                     */
           /*                                                     */
           /* Returns: short int                                  */
           /*-----------------------------------------------------*/
           short fn1 (char *p1, char *p2, char p3, ...)
    
    
    
            D fn1          PR            5I 0 EXTPROC(*CWIDEN1 : 'fn1')
            D   p1                        *   VALUE OPTIONS(*STRING) 2
            D   p2                      10A   OPTIONS(*RIGHTADJ) CONST 3
            D   p3                       1A   VALUE 4
            D   p4                      10I 0 VALUE OPTIONS(*NOPASS) 5
            D   p5                      10I 0 VALUE OPTIONS(*NOPASS)
    
    
    
    Notes on the answer to question 1:

    1. It's always a good idea to use *CWIDEN for C functions, but it's necessary in this case, because the return type is short, which is subject to widening, and because the third parameter is a char, which C expects to be passed as an integer-type.
    2. Use VALUE and OPTIONS(*STRING) when the function expects a null-terminated string. That way, you can pass character expressions directly to the function:
      fn1(file + '/' + lib : etc)
      
    3. The documentation does not say the parameter is a null-terminated string, so you should not code VALUE and OPTIONS(*STRING). Since the documentation says the parameter is 10 bytes, you can just code 10A. But since it is input-only, you can code CONST. A little-known feature of RPG is that you can do EVALR-type parameter passing, by coding OPTIONS(*RIGHTADJ). Since the parameter is documented to require right-adjusted data, it's a good idea to code this option.
    4. Since you use EXTPROC(*CWIDEN), you do not have to do anything special for this parameter.
    5. Even if you don't plan to pass these optional parameters, you must code at least one OPTIONS(*NOPASS) parameter for this prototype. If you do not do that, the C function will not receive the other parameters correctly.

  2.        /*-----------------------------------------------------*/
           /* fn2                                                 */
           /*-----------------------------------------------------*/
           /* Required parameters:                                */
           /*                                                     */
           /* Output: p1: integer (dimension of the second parm)  */
           /* Input:  p2: array of integers                       */
           /* Input:  p3: array of pointers to null-terminated    */
           /*             strings. The final pointer must be      */
           /*             null.                                   */
           /* Returns: none                                       */
           /*-----------------------------------------------------*/
           void fn2 (int *p1, int *p2, char *p3[]);
    
    
    
    
            D fn1          PR                 EXTPROC(*CWIDEN: 'fn2')
            D   p1                      10I 0
            D   p2                      10I 0 DIM(32767) 1
            D                                 CONST OPTIONS(*VARSIZE)
            D   p3                        *   DIM(32767)2
            D                                 OPTIONS(*VARSIZE)
    
    
    
    Notes on the answer to question 2:

    1. Since the documentation does not specify the exact dimension of the array, assume the maximum dimension (32767 prior to V6R1, much larger in V6R1), and code OPTIONS(*VARSIZE).
    2. "char *p3[]" is difficult to understand, but if you read it from right to left
      []
      *
      char
      
      you get "array of pointer to character". Since RPG does not have typed pointers, you can only code "array of pointers" in RPG. And code some large number for the dimension, with OPTIONS(*VARSIZE), since you don't know the actual dimension of the array.

  3.        /*-----------------------------------------------------*/
           /* num_recs                                            */
           /*-----------------------------------------------------*/
           /* Required parameters:                                */
           /*                                                     */
           /* Input: filename: 10 bytes, blank-padded             */
           /*                                                     */
           /* Returns: int                                        */
           /*                                                     */
           /* Notes:                                              */
           /* 1.  Compiling with DEFINE(DEBUG) will use a         */
           /*     version of this function that outputs           */
           /*     debugging information to stdout.                */
           /*-----------------------------------------------------*/
           #ifdef DEBUG
             #pragma map(num_recs, "num_recs_debug")
           #endif
           int num_recs (char filename[]);
    
    
    There are two ways to handle conditionally picking up one name or the other:
    1. Condition the EXTPROC keyword:
              D num_recs     PR
               /IF DEFINED(DEBUG) 1
              D                                 EXTPROC(*CWIDEN : 'num_recs_debug')
               /ELSE
              D                                 EXTPROC(*CWIDEN : 'num_recs')
               /ENDIF
              D   filename                10A   CONST
      
    2. Condition the definition of a named constant used on the EXTPROC keyword.
               /IF DEFINED(DEBUG)
              D  num_recs_name...
              D              C                  'num_recs_debug'
               /ELSE
              D  num_recs_name...
              D              C                  'num_recs'
               /ENDIF
      
              D num_recs     PR                 EXTPROC(*CWIDEN : num_recs_name)
              D   filename                10A   CONST
      
      
    Notes on the answer to question 3:
    1. If you know you always want one particular version of the function, it's not necessary to code the /IF DEFINED. But the version with /IF DEFINED is a more complete match for the C prototype.

Some background on C widening

Read this if you are curious about the need to code *CWIDEN.
Originally, C did not use prototypes; the C compiler would guess what type of parameter was being passed. This was fairly easy since C had only three basic data types, integer, float and pointer. Although it supported various lengths for these types, it only supported three parameter types for parameters passed by value. When the passed parameter had a shorter length from the supported parameter length, the parameter actually passed to the function was "widened" to be the length of the supported parameter type.
Here are the supported parameter types:
Long integer
These are the types that are widened to long integer:
  • single-byte character (3U 0)This implies single-byte character may be defined in RPG as 3U 0, not as 1A, when passing parameters to and from C by value, and handling procedure return values.But while defining the parameter or return value as 3U 0 may help, it will not completely solve the problem.
  • short integer (5I 0)
  • integer (10I 0)
  • long integer (10I 0)
  • short unsigned (5U 0)
  • unsigned (10U 0)
  • long unsigned (10U 0)
  • wchar_t (wide-charater) (1C or 1G)
Double float
These are the types that are widened to double float:
  • float (4F)
  • double (8F)
Pointer
*
Function pointer
(RPG * PROCPTR)
If, say, a short integer is passed as a parameter, it is widened to a long integer for passing; the called function receives the long integer and converts it to the type actually coded for the parameter.
Confused? Let's look at an example:
float f;

x = fn (3, f, &x);
(&x means the same as %addr(x) means in RPG)
The old C compilers didn't know anything about "fn". But they knew what to pass as a parameter here:
  • The first parameter is an integer of some kind, so it is passed as a long integer (RPG: 10I 0).
  • The second parameter is a float (RPG 4F), so it is passed as a long double (8F).
  • The third parameter is a pointer, so it is passed as a pointer.
Even though C normally uses prototypes now, all C compilers still widen parameters by default, and when a C function is called, the compiler assumes that the parameters were widened.

What does this mean to the RPG programmer?

Often, this doesn't seem to affect the RPG programmer at all. This is because problems due to widening are often hidden by fact that the system optimizes calls by using registers where possible. When a parameter is passed in a register, the fact that it was passed as 5i or 10i does not matter.
Problems with widening will typically show up when calls are made in complex expressions or when there are many parameters.
But even though problems don't often occur, it can be annoying and puzzling when they do crop up. Getting the prototype right in the first place will prevent the problem from ever happening.
Consider this C prototype:
     void fn(char c);
The obvious (but incorrect) RPG version is

     D fn           PR            8F   EXTPROC('fn')
     D   c                        1A   VALUE
When the RPG program calls the C function, the compiler will place the parameter in the first byte of the parameter area.
     callp        fn('A')

                     +---+
     Parameter area  | A |
                     +---+
The C compiler will assume that the parameter has been widened, so it will expect a 4-byte integer, which it will convert to a 1-byte unsigned integer.
                     +---+---+---+---+
     Parameter area  | A | x | y | z |
                     +---+---+---+---+

The 'A' will be ignored; the value that the function 'fn' will use is whatever happens to be in the 4th byte ('z' in this case).
Here is the correct RPG prototype:
     D fn           PR            8F   EXTPROC(*CWIDEN : 'fn')
     D   c                        1A   VALUE

End of document
Share:

Blog-Archiv

Powered by Blogger.

Blog Archive

Blogger templates