Hallo zusammen,
ich habe ein etwas außergewöhnliches Problem. Ich ergänze durch eigenen
C-Code das Ergebnis eines Codegenerators der Funktionen aus einem
Blockschaltbild von Matlab Simulink übersetzt.
Jetzt gibt es zwei Varianten, die in Simulink eingestellt werden können,
wobei ich aber vor der Laufzeit im DSP nicht weiß, welche es im Moment
ist.
So weit so gut. Das Problem ist, dass mir bei der einen Variante eine
Funktion GENERIERT wird, die ich auch aus meinem Code aufrufen muss, und
bei der anderen Variante nicht.
Also habe ich bspw. Variante 1 und die Funktion wird generiert, ist
alles i.O. Wenn jetzt aber Variante 2 generiert wird und ich die
Funktion nicht zur Verfügung habe, steht in meinem Code aber trotzdem
noch der Funktionsaufruf (der aber von Variante 2 während der Laufzeit
nie aufgerufen wird), der nun nicht aufgelöst werden kann. Dazu müsste
ich quasi eine Dummy Funktion schreiben. Dies würde aber bei Variante 1
zum Problem führen, da die Funktion dann zweimal definiert wäre.
Ich kann leider weder das Ergebnis des Codegenerators ändern, noch den
Codegenerator selber.
Hat jemand eine Idee wie ich das Problem lösen könnte?
Grüße
Eike
Hallo Eike
Deine Problembeschreibung ist leider etwas vage.
Welchen Codegenerator benutzt Du denn ?
Kann man da #pragma oder #define an den Compiler übergeben ?
Beim Standard mcc compiler kannst du zum Beispiel mit -Dxxx #defines
festlegen, die dann im C Code etsprechend ausgewertet werden können.
Ansonsten ist das Stickwort functionpointer.
Hth
Andreas
schau dir doch mal die Präprozessor Befehle
#ifdef
#ifndef
#elif
#else
#endif
an. Damit kann man defines steuern
z.B. ist bei Header dateien immer ein good practice die ganze Datei
so zu klammern. Damit hat man kein Problem falls die Header Datei über
eine andere Header Datei ggf. 2mal includiert wird.
#ifndef ___HEADER_NAME
#define ___HEADER_NAME
...
Header definitionen
...
#endif
Vielen Dank für die Antworten.
Ich versuche es noch etwas genauer zu erklären. Die #define und Co habe
ich mir bereits angeguckt bzw. sind bekannt aber nach meiner Ansicht
(korrigiert mich bitte) lösen sie nicht mein Problem.
Angenommen ich habe 2 Bibliotheken. 1 ist von mir geschrieben und die
andere wird für jeden Compiliervorgang vom CodeGenerator erzeugt.
Es wird Funktion xy() benötigt. Allerdings ist diese Funktion nur unter
bestimmten Umständen (die mir aber nicht angezeigt werden) in der
generierten Bibliothek vorhanden.
Nun muss ich, sofern die Funktion in der generierten Bibliothek nicht
vorhanden ist, diese in meiner Bibliothek vorhalten (eine Dummy-return-0
Funktion würde reichen) oder wenn sie in der generierten Bibliothek drin
ist, darf ich sie gar nicht in meiner Bibliothek haben, da sie sonst
redefined ist.
Ich benutze einen anwendungsspezifischen Coder, der nicht öffentlich
verfügbar ist. Das ganze wird dann im Code Composer Studio von TI
kompiliert.
Ich hoffe das war etwas verständlicher. :-)
Grüße Eike
Wenn die Funktion in einer "Bibliothek", also einer Library enthalten
ist, hast Du schlechte Karten. Der Compiler weiß nichts von Libraries,
um die kümmert sich erst der Linker.
Andreas H. schrieb:> Ansonsten ist das Stickwort functionpointer.
Wenn du dir mit GetProcAddress() die Adresse der Funktion besorgen
kannst, dann wurde die Funktion generiert und du kannst sie über den
Pointer aufrufen. Und du hast kein undefined-reference-Problem, wenn die
Funktion nicht generiert wurde.
Beim GNU-Linker und GCC kann man ein Symbol als "weak" definieren. Das
heißt, daß es quasi als Fallback verwendet wird, wenn kein anderes mit
dem selben Namen gefunden wird. Vielleicht gibt's bei deinem Compiler ja
sowas auch.
Konrad S. schrieb:> Wenn du dir mit GetProcAddress() die Adresse der Funktion besorgen> kannst
Das ist eine Funktion, um unter Windows Adressen von Funktionen in
geladenen DLLs zu bestimmen -- meinst Du nicht, daß es hier um etwas
komplett anderes geht? Der Threadstarter schrieb was von einem DSP, es
ist stark zu bezweifeln, daß auf dem Windows oder irgendwas anderes
läuft, was das Konzept einer DLL versteht.
Eike J. schrieb:> Ich benutze einen anwendungsspezifischen Coder, der nicht öffentlich> verfügbar ist. Das ganze wird dann im Code Composer Studio von TI> kompiliert.
Oh, anwendungsspezifische Coder benutzen wir auch. Bei uns heissen die
aber (oft) Studenten ;-)
Im Ernst: Wenn Du Code Composer Studio benutzt, dann schau Dir mal den
Linker Switch --priority an. Der Linker versucht dann unresolved
Functions in den Bibliotheken (und in der angegebenen Reihenfolge)
aufzulösen, in der die Libs in der cmdline des Linkers angegeben sind.
Das sollte Dein Problem eigentlich lösen.
Habs nicht ausprobiert sondern eben nur kurz nachgeschlagen. Also, wie
immer, ohne Garantie ;-)
Grüße
Andreas
Rufus Τ. Firefly schrieb:> Das ist eine Funktion, um unter Windows Adressen von Funktionen in> geladenen DLLs zu bestimmen -- meinst Du nicht, daß es hier um etwas> komplett anderes geht? Der Threadstarter schrieb was von einem DSP, es
Sorry, hab ich übersehen. Bin auf "Forum: PC-Programmierung"
reingefallen.
Peter II schrieb:> du könntest aber alle deine dummy funktionnen in eine lib packen und> diese dazulinken. Dann kann man doppelte funktionen ignorieren.
Wie ignoriere ich denn die doppelten? Bis jetzt kam immer wenn ich eine
Funktion zusätzlich als Dummy in einer Lib definiert habe, dass die
Funktion redefined ist.
Das wäre genau das wonach ich suche... :-)
Rolf Magnus schrieb:> Beim GNU-Linker und GCC kann man ein Symbol als "weak" definieren. Das> heißt, daß es quasi als Fallback verwendet wird, wenn kein anderes mit> dem selben Namen gefunden wird. Vielleicht gibt's bei deinem Compiler ja> sowas auch.
Das hab ich schon probiert, aber leider gibt es kein "weak" bei dem
Compiler.
Andreas H. schrieb:> Im Ernst: Wenn Du Code Composer Studio benutzt, dann schau Dir mal den> Linker Switch --priority an. Der Linker versucht dann unresolved> Functions in den Bibliotheken (und in der angegebenen Reihenfolge)> aufzulösen, in der die Libs in der cmdline des Linkers angegeben sind.
Gibt es den Linker Switch auch schon im CCS 3.3? Ich kann den weder in
den "Build Options" noch in der Hilfe finden.
Vielen Dank für die zahlreichen Antworten. Das stimmt mich ja noch
hoffnungsvoll.
Grüße Eike
Allgemein ist es so, dass statische Bibliotheken in der angegebenen
Reihenfolge durchlaufen werden und das erste passende Objekt wird in das
Programm übernommen. Wenn beim Linken also zuerst die Object-Files des
Programms genannt werden und danach die Bibliotheken, dann musst du nur
eine Dummy-Funktion in eine Bibliothek packen und diese Bibliothek beim
Linken mit angeben.
Das ist mit mehr Worten das, was Peter II oben geschrieben hat.
Konrad S. schrieb:> Allgemein ist es so, dass statische Bibliotheken in der angegebenen> Reihenfolge durchlaufen werden und das erste passende Objekt wird in das> Programm übernommen. Wenn beim Linken also zuerst die Object-Files des> Programms genannt werden und danach die Bibliotheken, dann musst du nur> eine Dummy-Funktion in eine Bibliothek packen und diese Bibliothek beim> Linken mit angeben.> Das ist mit mehr Worten das, was Peter II oben geschrieben hat.
Davon war ich ja auch ausgegangen. Aber wenn im generierten C-Code die
Funktion schon definiert war, hat der Compiler gemeckert wenn die
Funktion auch noch zusätzlich in der Lib stand. Habe ich vielleicht ein
Problem mit der Lib wenn er die behandelt wie normalen Code?
Grüße
Eike
Also irgendwie ist das seltsam, was Du schreibst. Da sollte der "Linker"
einen Fehler melden und nicht der Compiler. Und reden wir nun wirklich
von "Libraries"? Was ist das Deinem Verständnis nach? Ich verstehe
darunter eine Datei die compilierten Code zusammen mit einer
Symboltabelle und Einsprungadressen enthält.
Ich kann es gerade nicht ausprobieren, da es ohne die Hardware auf der
Arbeit nicht geht.
Ich habe ein Projekt vom Typ "Library (.lib)" erstellt, welches mir
eigentlich eine lib aus meinem C-Code machen sollte. Eigentlich war ich
davon ausgegangen, dass das richtig sei.
Allerdings bin ich mir nicht mehr sicher, dass die Fehlermeldung
tatsächlich vom Compiler und nicht vom Linker. Auf jeden Fall stand in
der Fehlermeldung, dass die entsprechende Funktion redefined ist.
Ich denke ich werde das am Montag nochmal genau dokumentieren und mich
melden...
Hast du die Dummy-Funktion in einer eigenen Quelltext- bzw.
Object-Datei? Das ist notwendig, weil ein Linker sich aus einer
statischen Bibliothek nur immer den Umfang einer Object-Datei holt, also
entweder ganz oder garnicht.
Konrad S. schrieb:> Hast du die Dummy-Funktion in einer eigenen Quelltext- bzw.> Object-Datei? Das ist notwendig, weil ein Linker sich aus einer> statischen Bibliothek nur immer den Umfang einer Object-Datei holt, also> entweder ganz oder garnicht.
Das hatte ich leider nicht. Vielen Dank für den Hinweis. Denn sollte es
dadran liegen. Das wäre super. Ich werde das Montag testen und mich
melden.
Ein schönes Wochenende
Eike J. schrieb:> Konrad S. schrieb:>> Hast du die Dummy-Funktion in einer eigenen Quelltext- bzw.>> Object-Datei? Das ist notwendig, weil ein Linker sich aus einer>> statischen Bibliothek nur immer den Umfang einer Object-Datei holt, also>> entweder ganz oder garnicht.>> Das hatte ich leider nicht. Vielen Dank für den Hinweis. Denn sollte es> dadran liegen. Das wäre super. Ich werde das Montag testen und mich> melden.>> Ein schönes Wochenende
Wie versprochen, nun die Rückmeldung. Es funktioniert wie du es
geschrieben hast, vielen Dank!