Forum: Mikrocontroller und Digitale Elektronik Funktion nur definieren wenn nicht schon vorher definiert


von Eike J. (Gast)


Lesenswert?

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

: Verschoben durch User
von Andreas H. (ahz)


Lesenswert?

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

von Udo S. (urschmitt)


Lesenswert?

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

von Eike J. (Gast)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

du könntest aber alle deine dummy funktionnen in eine lib packen und 
diese dazulinken. Dann kann man doppelte funktionen ignorieren.

von Konrad S. (maybee)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Andreas H. (ahz)


Lesenswert?

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

von Konrad S. (maybee)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Da hast Du übrigens recht -- das ist hier reichlich deplaziert.

-> verschoben.

von Eike J. (Gast)


Lesenswert?

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

von Konrad S. (maybee)


Lesenswert?

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.

von Eike J. (Gast)


Lesenswert?

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

von Noname (Gast)


Lesenswert?

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.

von Eike J. (Gast)


Lesenswert?

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...

von Konrad S. (maybee)


Lesenswert?

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.

von Eike J. (Gast)


Lesenswert?

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

von Eike J. (Gast)


Lesenswert?

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!

von Konrad S. (maybee)


Lesenswert?

Schön zu hören, dass es geklappt hat.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.