DEUTSCHE VERSION |
|
Links | | | Forums | | | Comments | | | Report news |
Chat | | | Polls | | | Newsticker | | | Archive |
amiga-news.de Forum > Programmierung > Library erzeugen | [ - Search - New posts - Register - Login - ] |
-1- | [ - Post reply - ] |
2004-04-08, 13:27 h Mazze Posts: 263 User |
Hi, ich trage mich mit dem Gedanken, aus GGTL eine Shared-Library für den Amiga zu erzeugen. Ich habe so etwas noch nie gemacht, und habe deshalb ein paar Fragen: Brauche ich eine Multbase-Library, um Funktionen aus der dos.library verwenden zu können? (Lesen und Schreiben in Dateien) Vermutlich muss ich die 'assert'-Funktionen durch etwas anderes ersetzen. Kann man gezielt Task-Held-Fehler auslösen? (Ein Guru ist mir zu brutal ) Im Aminet gibt es 2 Sachen, die man als Basis für shared libraries verwenden kann (Clib und SDI). Welches ist denn einfacher in der Handhabung? Ich brauche Hook-Funktionen. [ - Answer - Quote - Direct link - ] |
2004-04-17, 10:58 h Mazze Posts: 263 User |
Ich möchte folgende Funktion in eine Shared-Library einbauen:code:void sl_free(void *root, void (*func)(void*)) { struct sl_node *p; if (func == NULL) func = free; while ((p = sl_pop(&root))) func(p); } Ich bin davon ausgegangen, dass ich Callbacks mit "struct Hook" realisieren muss. Ich habe mir mal den Source der expat.library angeschaut. Dort wird nicht mit "struct Hook" gearbeitet. Wann braucht man "struct Hook"? Kann ich in einer Library die C-Funktion "free" aufrufen? [ - Answer - Quote - Direct link - ] |
2004-04-17, 12:01 h cygnusEd Posts: 104 User |
@Mazze > Ich bin davon ausgegangen, dass ich Callbacks mit "struct Hook" realisieren muss. Ich habe mir > mal den Source der expat.library angeschaut. Dort wird nicht mit "struct Hook" gearbeitet. > Wann braucht man "struct Hook"? Das kannst Du machen, wie es Dir am liebsten ist. Die Hook-Struktur ist nur der "Amiga-Weg", eine Funktion zu übergeben. Der Weg, wie er in Deinem Code-Schnipsel zu sehen ist, geht natürlich auch. Das Problem ist, daß die Hooks nur unter 68k vernünftig funtionieren. Die Argumente werden nämlich über die Register übergeben, was in einem PPC-System nicht ohne weiteres funktioniert. Um kompatibel zu bleiben, ist der andere Weg wohl besser. >Kann ich in einer Library die C-Funktion "free" aufrufen? Wenn Du den Speicher vorher mit malloc() (oder realloc()... ) angefordert hast - ja. Gruß CygnusEd [ - Answer - Quote - Direct link - ] |
2004-04-17, 16:27 h Mazze Posts: 263 User |
Zitat: Ok. Ich bin nur deshalb etwas vorsichtig, weil es heißt, dass eine Library-Funktion kein "forbid" unterbrechen darf. [ - Answer - Quote - Direct link - ] |
2004-04-17, 21:42 h obw Posts: 94 User |
Zitat: Dann mußt Du wohl die Doku deiner C-Bibliothek befragen. OBW [ - Answer - Quote - Direct link - ] |
2004-04-18, 19:46 h Holger Posts: 8116 User |
Zitat:Das ist komplett falsch. Wenn innerhalb einer 68k-Emulation Parameter in 68k-Registern übergeben werden, können selbstverständlich 68k-Anwendungen den 68k-Libraries problemlos Werte in Registern übergeben. Das ist der Normalfall für jede konventionelle Amiga-Libraryfunktion. Will man 68k-Anwendung und ppc-Library zusammen verwenden, muß man sich ohnehin mit der Implementation der Emulation des jeweiligen OS auseinandersetzen, egal, ob hook oder direkter Funktionspointer. Ein wesentlicher Punkt, den Du hier außer acht läßt, daß hooks im Gegensatz zu einfachen Funktionspointern die Aufrufkonvention genau definieren. Einfache Funktionspointer müssen nicht zwischen verschiedenen Compilern kompatibel sein und sind es insbesondere auf dem Amiga nicht, haben somit als Parameter in einer shared Amiga-Library nichts zu suchen. Nicht umsonst haben hook-Strukturen einen Platz für Compiler-spezifische stub-Funktionen. Auf einem PPC-OS mit definiertem vom compiler direkt unterstütztem ABI sieht das zwar anders aus, aber hier geht es um die "classic" 68k-Libraries. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ Dieser Beitrag wurde von Holger am 18.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-18, 19:58 h Holger Posts: 8116 User |
Zitat:Library-Funktionen können normalerweise von verschiedenen Tasks gleichzeitig aufgerufen werden, weshalb die Finger von sämtlichen Compiler-Funktionen lassen sollte, die möglicherweise nicht dafür ausgelegt sind, im Zweifelsfall alle. Die Speicherverwaltung gehört definitiv zu den problematischen Fällen. Wenn es um die Portierung von Software geht, die diese Funktionen nutzt, ist der beste Weg, einen header zu entwickeln, der die entsprechenden Funktionen auf sichere Amiga-spezifische umbiegt. Man kann nicht vermeiden, daß Library-Funktionen andere Funktionen aufrufen, die u.U. ein forbid() unterbrechen. Am einfachsten ist es, die Dokumentation dahingehend zu erweitern, daß ein Programmierer diese Funktion bei laufendem forbid() nicht aufrufen darf. Das entspricht sowieso der uralten Amiga-Konvention, daß ein forbid() nie länger als nötig dauern sollte. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2004-04-18, 23:17 h Mazze Posts: 263 User |
Als Basis für die Library verwende ich CLIB-SDI. Der Linker meldet folgendes:code:5.Work:CProj/ggtl-amiga/src/sl> ed makefile.gcc 5.Work:CProj/ggtl-amiga/src/sl> make -f makefile.gcc gcc -O2 -c -I ../include/C/ -D __NOLIBBASE__ -o libinitgcc.o libinit.c gcc -O2 -c -I ../include/C/ -D __NOLIBBASE__ -o slgcc.o sl.c gcc -noixemul -nostartfiles -s -o ../libs/sl.library libinitgcc.o slgcc.o /gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/libnix.a(free.o)(.tex t+0x2a): undefined reference to 'SysBase' /gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/libnix.a(free.o)(.tex t+0x46): undefined reference to 'SysBase' /gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/libnix.a(free.o)(.tex t+0x52): undefined reference to 'SysBase' /gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/libnix.a(malloc.o)(.t ext+0x18): undefined reference to 'SysBase' /gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/libnix.a(malloc.o)(.t ext+0x4e): undefined reference to 'SysBase' /gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/libnix.a(malloc.o)(.t ext+0x8a): more undefined references to 'SysBase' follow collect2: ld returned 1 exit status So sieht das Makefile aus: code:CFLAGS = -O2 -c -I ../include/C/ -D __NOLIBBASE__ LFLAGS = -noixemul -nostartfiles -s DDIR = ../libs/# the directory, where destination library is stored $(DDIR)sl.library: libinitgcc.o slgcc.o gcc $(LFLAGS) -o $@ libinitgcc.o slgcc.o libinitgcc.o: libinfo.h libinit.c gcc $(CFLAGS) -o $@ libinit.c slgcc.o: libinfo.h sl.c gcc $(CFLAGS) -o $@ sl.c Ich verstehe das nicht. SysBase wird in libinit.c definiert. Da ich aufgrund Holgers's posting free und malloc durch AmigaOs-Funktionen ersetzen werde, löst sich das Problem wahrscheinlich so nebenbei. Trotzdem interessiert mich mal, was hier los ist. [ Dieser Beitrag wurde von Mazze am 18.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-19, 09:57 h Mazze Posts: 263 User |
Nach dem ich free durch FreeVec ersetzt hatte, bekam ich bei dieser Funktion den Fehler mit der fehlenden SysBase. Der Fehler tritt nur auf, wenn ich die Funktionsadresse zuweise. ( z. B. func = FreeVec) Beim normalen Aufruf klappt das. Ich habe deshalb die Library-Funktion so umgebaut, dass keine Zuweisung der Funktionsadresse stattfindet. [ - Answer - Quote - Direct link - ] |
2004-04-19, 11:05 h gni Posts: 1106 User |
Zitat:Vieleicht als static. Der Linker kann aber kein globales SysBase finden. [ - Answer - Quote - Direct link - ] |
2004-04-19, 11:09 h gni Posts: 1106 User |
Zitat:Wenn Du die Funktionsadresse benutzt, dann verwendest Du den Stub aus libamiga.a. Alle dortigen Wrapper verwenden globale Librarybases (wie solls auch anders gehen?). Das Exec Symbol ist SysBase. [ - Answer - Quote - Direct link - ] |
2004-04-22, 19:31 h Mazze Posts: 263 User |
Hi, im Moment sieht es so aus, dass alles bis auf eine Sortierfunktion funktioniert. Um der Fehlerursache näher zu kommen: Was passiert, wenn sich eine Libraryfunktion rekursiv aufruft? Werden dann die Register gesichert oder muss ich mich selbst darum kümmern? [ - Answer - Quote - Direct link - ] |
2004-04-23, 16:41 h gni Posts: 1106 User |
Zitat:Das klingt nacht Stack-overflow. Zitat:Non-Scratch Register werden bei Funktionseintritt gesichert. Noch ein Hinweis: Library-funktionen (auch eigene!) sollten immer relativ zur Librarybasis aufgerufen werden. [ - Answer - Quote - Direct link - ] |
2004-04-23, 21:53 h cygnusEd Posts: 104 User |
@Holger > Das ist komplett falsch. Wenn innerhalb einer 68k-Emulation Parameter in 68k-Registern übergeben werden, können > selbstverständlich 68k-Anwendungen den 68k-Libraries problemlos Werte in Registern übergeben. > Das ist der Normalfall für jede konventionelle Amiga-Libraryfunktion. > Will man 68k-Anwendung und ppc-Library zusammen verwenden, muß man sich ohnehin mit der Implementation der Emulation > des jeweiligen OS auseinandersetzen, egal, ob hook oder direkter Funktionspointer. Da habe ich mich wohl etwas undeutlich ausgedrückt. In einer simulierten Umgebung funtioniert das natürlich auch auch mit jedem anderen Prozessor. Aber das meinte ich nicht - direkt läuft's eben nicht. > Ein wesentlicher Punkt, den Du hier außer acht läßt, daß hooks im Gegensatz zu einfachen Funktionspointern die > Aufrufkonvention genau definieren. > Einfache Funktionspointer müssen nicht zwischen verschiedenen Compilern kompatibel sein und sind es insbesondere auf dem > Amiga nicht, haben somit als Parameter in einer shared Amiga-Library nichts zu suchen. > Nicht umsonst haben hook-Strukturen einen Platz für Compiler-spezifische stub-Funktionen. > Auf einem PPC-OS mit definiertem vom compiler direkt unterstütztem ABI sieht das zwar anders aus, aber hier geht es > um die "classic" 68k-Libraries Da hast Du allerdings recht. Das habe ich nicht zu Ende gedacht. Eine Funktion kann so nicht von Programmen aufgerufen werden, die mit unterschiedlichen Compilern erzeugten wurden. Ist also eher was für Link-Libraries ;-) Den PPC hatte ich auch nur erwähnt, um zu unterstreichen, daß Hooks nur für 68k-Amigas interessant sind. > Library-Funktionen können normalerweise von verschiedenen Tasks gleichzeitig aufgerufen werden, weshalb die Finger von > sämtlichen Compiler-Funktionen lassen sollte, die möglicherweise nicht dafür ausgelegt sind, im Zweifelsfall alle. > Die Speicherverwaltung gehört definitiv zu den problematischen Fällen. Wenn es um die Portierung von Software geht, die > diese Funktionen nutzt, ist der beste Weg, einen header zu entwickeln, der die entsprechenden Funktionen auf sichere > Amiga-spezifische umbiegt. > Man kann nicht vermeiden, daß Library-Funktionen andere Funktionen aufrufen, die u.U. ein forbid() unterbrechen. Am > einfachsten ist es, die Dokumentation dahingehend zu erweitern, daß ein Programmierer diese Funktion bei laufendem > forbid() nicht aufrufen darf. > Das entspricht sowieso der uralten Amiga-Konvention, daß ein forbid() nie länger als nötig dauern sollte Um 100%ig sicher zu sein, ist das wohl richtig. Zwischen Forbid() und Permit() sollte man aber sowieso nur die einfachsten Funktionen ausführen. Außerdem muß man gelegendlich auch beim Aufruf von Amiga-Shared-Lib-Funktionen vorsichtig sein, wie z.B. bei Wait(), WaitPort() etc. Die Problematik mit Forbid() stand aber auch zuerst nicht zur Debatte. MfG [ - Answer - Quote - Direct link - ] |
2004-04-23, 22:50 h Mazze Posts: 263 User |
Zitat: Ich habe mich ungenau ausgedrückt. Die Funktion wird absichtlich rekursiv aufgerufen. Ich muss vermutlich non-scratch-Register verwenden. Zitat:Non-Scratch Register werden bei Funktionseintritt gesichert. Noch ein Hinweis: Library-funktionen (auch eigene!) sollten immer relativ zur Librarybasis aufgerufen werden. [/quote] Bei den eigenen Funktionen kenne ich den Prototyp. Aber in den Protos der Systemlibraries taucht doch der Basepointer gar nicht auf? Zum Thema Stack: Übernimmt eine Library den Stack des aufrufenden Programmes? Habe ich überhaupt eine Chance zu verhindern, dass eine Libraryfunktion die Stackgrenze überschreitet? MFG Matthias [ - Answer - Quote - Direct link - ] |
2004-04-24, 14:45 h Holger Posts: 8116 User |
Zitat:Bei den Systemlibraries mußt Du Dich auch nicht selbst darum kümmern. Das machen die stubs/inlines automatisch für Dich. Es ging wohl mehr um die Aufrufkonventionen für Deine eigene Library, wobei ich das nicht so pauschalisieren würde. Eine rekursive Funktion würde ich z.B. nicht jedesmal über den Library-Einsprung realisieren. Zitat:Ja, Deine Funktion läuft mit dem Stack des aufrufenden Programms. Es gibt eine dokumentierte Mindestgröße (4096 für normale Programme, 1024 für bestimmte entsprechend dokumentierte Funktionen), die der Stack einer Anwendung haben muß, um die standard-Bibliotheken nutzen zu dürfen. Wenn Deine Bibliothek davon abweicht, mußt Du das zumind. dokumentieren. Natürlich könnte Deine Bibliothek die Stackgröße des Aufrufers überprüfen, aber von einem solchen Overhead rate ich ab. Alternativ kann man natürlich für die Dauer eine Funktion einen neuen Stack erzeugen, das gehört aber schon in den Bereich sehr trickreicher Programmierung, die u.U. auf neuen Systemen Probleme macht. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2004-04-24, 14:53 h Holger Posts: 8116 User |
Zitat:Uninteressant ist es für ppc auch nicht. Man muß nur wissen, daß, wenn man hooks in Library-APIs verwendet, die Software nicht mehr mit einem einfachen re-compile auf den ppc portiert werden kann. Man muß sich dann direkt mit der Abwärtskompatibilität und 68k-Emulation auseinandersetzen und u.U. eine abweichende API in der PPC-Version anbieten. Aber das sollte nicht dazu führen, daß man jetzt komplett auf callbacks verzichtet. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2004-04-27, 08:46 h gni Posts: 1106 User |
Zitat:Das habe ich auch so verstanden. Und genau das verursacht auch den Stackoverflow. Library-Funktionen laufen immer im Context des Programmes, das die Library benutzt. Wenn das Programm "wenig" Stack hat, Du aber viel benötigst, gibts einen Crash. Entweder Du verlangst genügend Stack oder Du wechselst den Stack, wenn zuwenig da ist. Zitat:Library-Funktionen werden _immer_ relativ zur Librarybasis aufgerufen. Direkte Aufrufe sind nicht möglich. Der Prototyp in clib/ ist nicht der Name der "echten" Funktion im Quell-code sondern der des Einsprungs relativ zur Basis.Zitat:Bei den eigenen Funktionen kenne ich den Prototyp. Aber in den Protos der Systemlibraries taucht doch der Basepointer gar nicht auf? [ - Answer - Quote - Direct link - ] |
2004-04-27, 11:25 h thomas Posts: 7718 User |
Zitat: Das stimmt so nicht. Wenn du nur die clib/xyz_protos.h einbindest und die amiga.lib dazulinkst, hat jede OS-Funktion einen C-Stub, der ganz normal mit Stack-Parametern aufgerufen wird und auch eine absolute Adresse hat. Nur wenn du die pragmas (bzw. inlines) mit einbindest, wird der Compiler die OS-Funktion direkt relativ zur Library-Base und mit Parametern in Registern aufrufen. Und dann hat die Funktion natürlich keine absolute Adresse mehr. Gruß Thomas -- Email: thomas-rapp@web.de Home: home.t-online.de/home/thomas-rapp/ [ - Answer - Quote - Direct link - ] |
2004-04-27, 16:06 h obw Posts: 94 User |
Zitat: Interessante Frage: Wie stelle ich fest, ob zu wenig da ist? Spontan würde ich sagen: StackSwap() auf Verdacht und dann stk_Pointer und stk_Lower vergleichen. Dann wieder zurückswappen. Kann man als Stack für die StackSwapStruct einfach beliebig allozierten Speicher verwenden (Alignment?)? Zitat: Wenn ich also eine Funktion habe, die sich z.B. rekursiv durch einen Baum arbeitet, mache ich das am besten wie? so? code:ULONG lib_func(ULONG foo) { return do_func(ULONG foo); } static ULONG do_func(ULONG foo) { [...] bar = do_func(bar); [...] } korrekt? Für lib_func() gibt es ein öffentliches Interface in den Includes. do_func() ist rein intern. Im anderen Fall müßte ich noch mit Registern jonglieren und das ganze ist nicht mehr trivial compiler-portabel. OBW [ - Answer - Quote - Direct link - ] |
2004-04-27, 19:48 h Mazze Posts: 263 User |
Zitat: Angenommen, ich habe in einer Funktion eine Variable auf ein Scratch-Register gelegt. Wenn ich jetzt eine Betriebssystem-Funkion aufrufe, die ihre Parameter ebenfalls auf Scratch-Register leitet, dann wird doch aus einem Call-by-Value ein Call-by-Reference-Aufruf. Sehe ich das richtig? Die Betriebssystem-Funktion kann doch "hintenrum" den Registerwert veränderen. Wie kommt den der Kompiler bzw. Optimizer damit zurecht? [ - Answer - Quote - Direct link - ] |
2004-04-27, 20:43 h thomas Posts: 7718 User |
Das Scratch-Register muß nach dem Funktionsaufruf als verändert angesehen werden, da kann man keine Variable rein legen. Deshalb heißt es ja Scratch. Assembler kennt kein "by-value" oder "by-reference". In Assembler gibt es nur globale Variablen, die von den Unterprogrammen verändert werden können. Daß bestimmte Register als Nicht-Scratch angesehen werden, ist eine Konvention, kein Gesetz. Gruß Thomas -- Email: thomas-rapp@web.de Home: home.t-online.de/home/thomas-rapp/ [ - Answer - Quote - Direct link - ] |
2004-04-28, 08:54 h gni Posts: 1106 User |
Zitat:Machst Du Assembler oder C? In C mußt Du Dich um so was nicht kümmern. Das erledigt der Compiler für Dich, weil er sich an ein ABI hält. Soll heißen, Parameter kannst Du in SCratch-registern übergeben, da der Compiler die Argumente bei Bedarf an einen "sicheren" Ort bringt. [ Dieser Beitrag wurde von gni am 29.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-28, 09:02 h gni Posts: 1106 User |
Zitat:Normalerweise über die SP-Einträge in der Task-Struktur bzw. Einträge in der Process-Struktur wenn das Programm aus der Shell gestartet wird. Wurde der Stack bereits ausgetauscht ohne StackSwap(), dann bekommet man ein "falsches" Ergebnis". Bei getauschtem Stack eines Shell-programms würde man auch "falsche" Werte bekommen egal wie der Stack getauscht wurde. Solange das Ergebnis lautet "zu klein" geht alles glatt ;-) War der Stack groß genug, wird ja wohl niemand auf die Idee gekommen sein ihn zu tauschen. Was man eigentlich wissen will ist, ob noch genügend Platz ist. Zitat:Ja.Zitat:Wenn ich also eine Funktion habe, die sich z.B. rekursiv durch einen Baum arbeitet, mache ich das am besten wie? so? Zitat:Ich bezog mich auf die öffentliche Funktion, die muß immer relativ zur Basis aufgerufen werden. Was dann weiter intern passiert, ist Sache der Bibliothek. [ - Answer - Quote - Direct link - ] |
2004-04-28, 09:04 h gni Posts: 1106 User |
Zitat:Dennoch wird auch hier die Libraryfunktion relativ zur Basis aufgerufen und genau darauf kommt es an. Es ist völlig unerheblich, an welcher Stelle der relative Aufruf erfolgt. Hauptsache es wird so gemacht :-) [ - Answer - Quote - Direct link - ] |
2004-04-28, 19:51 h Mazze Posts: 263 User |
Zitat: Ich programmiere in C und zwar gcc3.3 unter Amithlon/AOS3.9BB2. Wenn ich in einem normalen C-Programm Registervariablen verwende, dann trifft es auf jeden Fall zu, dass die Registerinhalte an einen sicheren Ort gebracht werden. Aber was passiert, wenn ich eine Library-Funktion aufrufe? Weis der C-Kompiler, dass bestimmte Register (Scratch) "hinterrücks" von den Library-Funktionen verändert werden können? Ich habe jetzt mal in der Library die Registerparameter a0 und a1 durch a3 und a5 ersetzt. Jetzt bekomme ich im Test-Programm einen Parse-Error. Als Ursache vermute ich folgendes Makro im Inline-Header: code:#define sl_map(root, func, data) LP3A5(0x3c, APTR, sl_map, APTR, root, a2, struct Hook *, func, a3, APTR, data, d7, , SL_BASE_NAME) Hier fällt zunächst mal auf, dass der 3. Parameter statt auf a5 auf d7 liegt. In meinem inline/macros.h ist kein LP3A5 definiert. Hier klappt offenbar das Zusammenspiel zwischen fd2pragma und gcc nicht. Frage: gibt es einen Unterschied zwischen Adress- und Wert-Register? Kann ich eine Adresse an ein Wert-Register übergeben? Oder muss ich mich übergeben? [ Dieser Beitrag wurde von Mazze am 28.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-29, 13:09 h gni Posts: 1106 User |
Zitat:Also C. In diesem Fall mußt Du Dir um Scratch-Register _keinen_ Kopf machen. Der Compiler kümmert sich um die Details. BTW, Du weisst, das GCC 3.3 unter Umständen bei Verwendung von LP-Inlines nicht-funktionierenden Code erzeugt? Das kann mit einem Update von inline/macros.h behoben werden, das aber noch nicht verfügbar ist :-( Zitat:Was ist für Dich eine Register-Variable? Eine lokale Variable mit "register" Zusatz? Oder redest Du von Parameterübergabe in Registern? Zitat:Alle Libraries müssen AmigaOS-ABI konform sein, soll heissen alle non-scratch Register _müssen_ nach dem Funktionsaufruf den selben Wert wie _vor_ dem Funktionsaufruf haben. Scratch-Register _können_andere Werte haben, aber sie _müssen_ nicht. Wenn eine Funktion vom allgemeinen Schema abweicht, ist das meist dokumentiert (zb. Forbid/Permit, etc.) aber das ist nur für Assembler wirklich interessant. Für den Compiler ist der OS-Funktionsaufruf wie jeder andere, dh. er erwartet das "Standardverhalten". Zitat:a4/a5[/a6/a7 ;-)] vermeiden. a4 und a5 werden vom Compiler verwendet. a0 und a1 sind vollkommen korrekt. Zitat:und das Maktro heisst LP3_A5_. A5 kann nicht ohne weiteres als Argumentregister verwendet werden. Deshalb wird das Argument erst nach d7 (hoffentlich ist das frei ;-) gepackt und danach nach A5. Das wird vom speziellen LP Makro erledigt. Zitat:inline/macros.h enthält nur die Makros., die von OS-Funktionen verwendet werden. Wenn eine 3rd-Party Library eine Kombination verwendet, die eine System-Libraries nicht hat, dann fehlt das Makro. Du solltest Dir für Deine Library ein Inline erzeugen, die die LP Makros "direkt" verwendet (ohne Einbindung von inlines/macros.h). Zitat:Die Frage verstehe ich nicht. [ Dieser Beitrag wurde von gni am 29.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-29, 23:54 h Mazze Posts: 263 User |
Zitat: Gut Zitat: Habe ich nicht gewusst. Allerdings muss ich ein #define setzen, wenn ich ReAction-GUIs erstelle. Dies hat möglicherweise etwas mit den LP-Makros zu tun. Zitat: OK Zitat: OK Zitat:Eine C-Funktion mit einem Pointer als Argument:Zitat:Die Frage verstehe ich nicht. Bsp: void test(void *p) würde ich in einer Library mit den Makros aus Clib-SDI folgendermaßen deklarieren ASM(VOID) LIBtest (REG(a0, APTR p)) Kann ich a0 durch d0-7 ersetzen? Leute, ich stelle das Thema "Library erzeugen" erstmal zurück und binde stattdessen den C-Code direkt ein. Wahrscheinlich habe ich einen Fehler gemacht, den ich erst finde, wenn ich mit etwas zeitlichem Abstand noch mal von vorne anfange. [ - Answer - Quote - Direct link - ] |
2004-04-30, 12:54 h gni Posts: 1106 User |
Zitat:Das ReAction-Define hat wohl nichts mit der GCC3+LP Makro Problematik zu tun. Zitat:Ja. Manchmal ist es natürlich von Vorteil, wenn man Zeiger in Adressregistern übergibt. Da spart man sich u.U. ein "move". BTW, Ergebnisse werden unter AmigaOS/68k immer über _D0_ geliefert. Auch Zeiger ;-) Zitat:Ich weiss nicht wie Du es gemacht hast, aber ich würde wohl Wrapper für die Original-Funktionen schreiben, da man dann die Originalquellen nicht ändern muß. Das macht die Bibliothek leider etwas langsamer, ist aber viel besser wartbar. [ - Answer - Quote - Direct link - ] |
2004-05-08, 15:48 h Mazze Posts: 263 User |
Ich habe die GGTL* auf den Amiga portiert. Mittlerweile sehe ich keinen großen Sinn mehr darin, eine Runtime-Library zu erzeugen. Ich binde einfach den C-Source eine und erspare mir dadurch den Stress mit Registern, Hooks und Wrappern für Standard-C-Funktionen. Falls sich mal jemand meinen Versuch, eine Runtime-Library zu erzeugen, anschauen will: Download Es ist das Programm test-mergesort, das Fehler meldet. * Generic Game Tree Library. (Library zum Erzeugen von "intelligenten" Spielen wie Othello, Dame, Schach etc.) GGTL Amiga Port Original Linux-Version Es wird wohl noch ein paar Tage dauern, bis es im Aminet erscheint. [ - Answer - Quote - Direct link - ] |
-1- | [ - Post reply - ] |
amiga-news.de Forum > Programmierung > Library erzeugen | [ - Search - New posts - Register - Login - ] |
Masthead |
Privacy policy |
Netiquette |
Advertising |
Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved. |