amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > c Funktionen und Parameterübergabe in Registern [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

31.05.2002, 00:47 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Hi, ich habe ein kleines Problem, ich möchte aus meinem Programm eine
Library Funktion aufrufen der ich einen Zeiger auf eine Funktion in meinem Programm übergeben muss und diese Library soll diese Funktion aurufen können, wobei Sei einen Parameter in einem bestimmten Register übergeben soll.

Da solche Sachen und deren definition in C nicht so einfach sind, hoffe ihr könnt mir helfen, wie ich die Sachen definieren muss, d.h. die Funktion definiere und diese dann aufrufe.

In erster Linie geht es, wie ich die Sachen in der Library in C erledige.

Gruss.

[ - Antworten - Zitieren - Direktlink - ]

31.05.2002, 06:56 Uhr

Kronos
Posts: 1168
Nutzer
Welcher Compiler ?

SAS, StormC1-3 oder StormC4/GCC ?

MfG
Kronos
--

Only the good die young all the evil seem to live forever

[ - Antworten - Zitieren - Direktlink - ]

31.05.2002, 09:32 Uhr

Solar
Posts: 3680
Nutzer
Das Problem ist, das die Übergabe in Registern nicht Teil des C-Standards ist (das Schlüsselwort "register" ist nur eine Empfehlung an den Compiler, und sagt nichts darüber *welches* Register), sondern Compiler-spezifisch geregelt werden muß (#pragma, compiler-spezifische Schlüsselwörter).

[ - Antworten - Zitieren - Direktlink - ]

31.05.2002, 09:53 Uhr

Holger
Posts: 8116
Nutzer
Das Aufrufen einer library-Funktion erfordert mehr als nur die Übergabe in Registern. Es gibt da noch einen Library-Pointer, der im Register a6 übergeben wird, aus C-Compilersicht ein weiterer Parameter. Und der Aufruf selbst ist relativ zu diesem Adressregister, was völlig anders ist als bei normale C-Funktionen.

Deshalb gibt es für die system-libraries header-Dateien, die man per #include einbinden kann, um die library-Funktionen wie normale C-Funktionen benutzen zu können. Wenn Du die hast, brauchst Du Dich um die Eigenheiten der Registerübergabe nicht mehr zu kümmern.
Und für die meisten Compiler gibt es Tools, die eine solche header-Datei auch aus fd-Dateien generieren können. Man will so etwas normalerweise nicht von Hand machen.

(Nur um sicher zu gehen, will ich hier nochmal erwähnen, daß die Registerübergabe bei der Definition, nicht beim Aufruf sichergestellt wird.)

mfg

--

Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

31.05.2002, 11:53 Uhr

thomas
Posts: 7716
Nutzer

Hallo DariusBrewka,

du solltest etwas spezifischer werden. Wenn du eine AmigaOS-Funktion (z.B. OpenWindow oder so) aufrufen möchtest, reicht es, die entsprechenden Prototypen (z.B. clib/intuitition_protos.h) einzubinden. Der Compiler hat für alle Funktionen sog. Stubs, die die Register laden und die Funktion aufrufen. Wenn es zweitkritische Aufgaben sind, kannst du auch die pragmas (z.B. pragmas/intuition_pragmas.h) einbinden. Dann generiert der Compiler den Aufruf mit Registern direkt in den Programmcode. Die Syntax der Pragmas ist allerdings compilerabhängig und die Pragmas sind nicht bei jedem Compiler dabei. Wie Holger sagt, gibt es Tools, die das erledigen (meist fd2pragma oder so), aber das ist nicht jedermanns Sache. Außerdem gehen dem Compiler manchmal die Register aus, wenn zu viele Funktionen aufgerufen werden.

Wenn du eigene Funktionen schreibst, die Register brauchen (z.B. Callback-Hooks), dann gibt es auch bei jedem Compiler eine (andere) Lösung dafür.

Bei Dice geht es z.B. so:

__saveds ULONG funktion(register __A0 char *pointer);

Wenn man die Library-Base in A6 braucht und der Compiler die nicht zerstören darf, kann man die als Trick mit in die Parameterleiste aufnehmen:

__saveds ULONG funktion(register __A0 char *pointer,register __A6 struct Library *DOSBase);

__saveds sorgt dafür, daß ggf. das Basis-Register A4 (im Small-Data-Model) neu geladen wird.

Auf jeden Fall lohnt es sich bei solchen Sachen immer, sich die Assembler-Liste ausgeben zu lassen und zu kontrollieren, ob der Compiler alles richtig gemacht hat.

Gruß Thomas

--
Email: thomas-rapp@web.de

Home: home.t-online.de/home/thomas-rapp/


[ - Antworten - Zitieren - Direktlink - ]

31.05.2002, 12:26 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Vieleicht etwas genauer, ich benutze den VBCC Compiler, mit einem anderen würde das im Moment nicht laufen, bzw ich habe es zum laufen bekommen, aber seht selber es ist patchwork:

(Hoffe das der Code Lesbar ist)

VBCC spezifisch, und schlecht!
void __PaintTool(__reg("a0") APTR hd, __reg("a4") APTR *func)="\tjsr\ (a4)";
#define PaintTool(hd, func) __PaintTool((hd), (func))
ende des VBCC spezifischen Zeuchst

struct newT {
APTR pool;
APTR hd;
ULONG *bm;
ULONG *buffer;
UWORD w;
UWORD h;
void *paint; //(REG(a0) APTR *));
};

der Parameter "tool" zeigt immer auf eine Struktur des Types newT

void SAVEDS ASM InitTool(REG(a0) APTR tool, REG(a1) APTR bm, REG(a2) APTR buffer, REG(a3) void *func, REG(a4) APTR t) {

((struct newT *) tool)->hd = t;
((struct newT *) tool)->paint = func;
}

void SAVEDS ASM StartTool(REG(a0) APTR tool) {
PaintTool(((struct newT *) tool)->hd, ((struct newT *) tool)->paint);
}

das ist ein Ausschnitt aus meinem Library Code, mein Hauptprogramm ruft die InitTool Funktion auf, und soll dieser einen Zeiger auf eine Funktion übergeben. InitTool soll diesen Zeiger sichern.
Wenn mein Programm dann die StartTool Funktion aufruft, soll diese hier Beispielweise die in InitTool übergebene Funktion aufrufen wobei diese Funktion ein Argument arwartet, welches im Register a0 übergeben werden muss.

Wie ihr seht ist das nicht sehr schön gelöst, und Zeiger sind in C etwas was mich stört, da ich damit immer Probleme habe.

Inzwischen denke ich aber, dass das mit Hooks eigentlich besser zu lösen wäre, vor allem Kompatibler.

Ich hoffe es ist zu Verstehen, was gemeint ist.

Diese Library ist privat, d.h nur von meinem Programm zu nutzen, so eine Art Plugin.

Danke an alle

Darius

[ - Antworten - Zitieren - Direktlink - ]

31.05.2002, 12:39 Uhr

Solar
Posts: 3680
Nutzer
Zitat:
Original von DariusBrewka:
Wie ihr seht ist das nicht sehr schön gelöst, und Zeiger sind in C etwas was mich stört, da ich damit immer Probleme habe.


Darius, dann hast Du ein sehr viel grundlegenderes Problem als Registerübergaben... ohne ein solides Verständnis von Zeigern wirst Du mit C immer Schiffbruch erleiden (außer bei trivialst-Programmen)...
?(

[ - Antworten - Zitieren - Direktlink - ]

31.05.2002, 18:23 Uhr

thomas
Posts: 7716
Nutzer

Du solltest dir eins merken: Keep it simple !

Wenn es sich doch sowieso um Routinen handelt, die nur du benutzt, mach es in C und laß die dummen Register raus. Spätestens mit OS4 wirst du sonst arge Probleme bekommen.

Außerdem solltest du statt APTR lieber die richtigen Typen benutzen. Dann mußt du nicht dauernd casten und der Compiler überprüft für dich, ob du alles richtig gemacht hast.

Sieht das hier nicht sehr viel einfacher aus:

code:
#include <stdio.h>

struct arguments {
char *arg1;
char *arg2;
};

typedef int (*toolfunct) (struct arguments *args);

struct Tool {
toolfunct function;
char dies;
short und;
long das;
};

/* --------------------------------- */

void InitTool (struct Tool *tool,toolfunct funct)
{
tool->function = funct;
} 

/* --------------------------------- */

int StartTool (struct Tool *tool,struct arguments *args)
{
return ((tool->function)(args));
}

/* --------------------------------- */

int beispiel (struct arguments *args)
{
printf ("arg1 = %s\n",args->arg1);
printf ("arg2 = %s\n",args->arg2);
return (5);
}

/* --------------------------------- */

int main (void)
{
struct Tool tool;
struct arguments args = {"Hund","Katze"};
int res;

InitTool (&tool,beispiel);
res = StartTool (&tool,&args);
printf ("Ergebnis: %d\n",res);

return(0);
}


Gruß Thomas

--
Email: thomas-rapp@web.de

Home: home.t-online.de/home/thomas-rapp/


[ - Antworten - Zitieren - Direktlink - ]

01.06.2002, 00:32 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
@Solar

nuja, dafür habe ich viele kleine persönlich Tools geschrieben und ein (nicht nur meiner Meinung nach) sehr schönes StartMenu.
Vieleicht war von keine Ahnung von Zeigern auch übertrieben, aber manchmal ist das doch kompliziert oder??? ;-)

@Tomas

APTR nehme ich, da die eigentlich Struktur wahlfrei ist und keinen bestimmten Type haben soll. Aber eigentlich hast du schon Recht.

Das mit den Nichtbenutzen von Registern wäre schön, aber wie? ich glaube es ist noch nicht klar, was gemeint ist.

Du hast alles in ein Programm gepackt, aber das kann ich nicht machen, bei mir ist die aufzurufende Funktion in einen anderen Programm und die Funktion die diese Funktion aufruft in einer Library (weil man Libraries so schön nachladen kann).

Irgendwie muss ich da Sicherstellen, dass das Argument ankommt.

egal, ich werde das mit Hooks lösen (habe es an anderer Stelle auch schon, nur bin ich da nicht mehr darauf gekommen) :-)

danke für deine (eure) Mühe.

Darius

[ - Antworten - Zitieren - Direktlink - ]

01.06.2002, 00:35 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Entschuldigung habe das 'h' vergessen Thomas.

gruss

Darius

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > c Funktionen und Parameterübergabe in Registern [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.