Hallo
ich habe ein Problem unter linux an dem ich verzweifle. Das Problem
besteht sowohl in eclipse als auch beim compilieren auf der console
folgende files sind vorhanden:
main.c:
die dazugehörige libk8055.so liegt in /usr/local/lib
es gibt eine /etc/ld.so.conf.d/k8055.conf mit dem inhalt /usr/local/lib
laut dem Ersteller der lib (http://libk8055.sourceforge.net/)kann man
diese einfach so nutzen:
gcc -Wall -lk8055 main.c
mache ich das, erhalte ich als Fehlermeldung:
Nicht definierter Verweis auf 'OpenDevice'
Nicht definierter Verweis auf 'WriteAllDigital'
die gleichen Fehler meldet auch Eclipse. Das Header File findet eclipse
Das der lib beigefügte Testprogramm funktioniert und bringt auch beim
make keine Fehler. Ich habe zum Test auch mal alle includes des
originalen Testprogramms in mein kleines Programm eingefügt,
funktioniert auch nicht.
So langsam bin ich am Ende meiner Weisheit.
Normalerweise müsste der Code, an dem ja nicht viel dran ist, doch so
funktionieren oder übersehe ich da etwas?
Gruß René
Danke für die Info
hat zum Teil geholfen. Die "Nicht definierter Verweis" Fehler sind weg.
Dafür meckert der gcc jetzt Funktionen an in der libk8055.so die wohl in
der libusb drin sind. Erweitere ich die Zeile auf
1
gcc -Wall main.c -lk8055 -lusb
verschwinden die Fehler bis auf einen:
Nicht definierter Verweise in libk8055.so auf sqrtf
Irgendwie ist das suspekt. Warum meckert der Funktionen in einer
gelinkten lib an? Vielleicht kann mir da noch jemand helfen solche
Probleme hatte ich bisher noch nie. Obgleich ich zugeben muss ich habe
lange nichts mehr programmiert und bisher immer nur die "Standard" libs
benutzt.
Gruß René
g457 schrieb:> Weil sie fehlt?
ja aber gerade das wundert mich halt. Die libk8055 ist doch bereits
erstellt und beim ursprünglichen compilieren der lib wurde doch die
libusb etc. bereits mit verlinkt. Ich dachte eigentlich immer das alles
was bereits in libs eingebaut ist muss dann nicht mehr angegeben werden.
Irgendwie stehe ich da grade bisserl auf dem Schlauch.
gcc -Wall main.c -lk8055 -lusb -lm -o main führte dann übrigens zu einer
funktionierenden ausführbaren Datei... nun muss ich das nur noch in
Eclipse hinbekommen. Am Ende soll da mal etwas mit gui werden wobei es
für die Vellemann k8055 auch eine qtk8055lib gibt, die habe ich jedoch
noch nicht getestet.
Gruß René
René S. schrieb:> g457 schrieb:>> Weil sie fehlt?>> ja aber gerade das wundert mich halt. Die libk8055 ist doch bereits> erstellt und beim ursprünglichen compilieren der lib wurde doch die> libusb etc. bereits mit verlinkt.
Nein.
> Ich dachte eigentlich immer das alles> was bereits in libs eingebaut ist muss dann nicht mehr angegeben werden.
Das wurde sie nicht.
Versuche doch einmal selbst eine Library zu erzeugen.
Hier gibt es eine Anleitung:
http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
die ich mit dem Suchterm: "erstellen einer library" gefunden habe. (Ist
allerdings ein Beispiel für'n PIC). Damit findet man sicher noch
anderes, was Dir mehr Informationen gibt.
Es wäre auch kontraproduktiv, Funktionen aus anderen Libraries in die
neu erzeugte Library zu übernehmen (im Sinne von kopieren). Nimm an, Du
möchtest mehrere Libraries verwenden, die aller wiederum eine bestimmte
Funktion aus einer dritten Library verwenden. Wenn jede davon eine Kopie
der Funktion enthält, wäre das ineffektiv.
Gut. Man könnte da Gegenmaßnahmen überlegen, aber das einfachste ist,
eben nur einen Verweis hinzuzufügen, der dann am Ende, vom Linker zu
einer einzigen Kopie dieser Funktion führt. Das entspricht ohnehin der
Vorgehensweise beim erzeugen von Objekt-Dateien (eine Library ist in
gewisser Weise nur eine besondere Form von Objekt-Datei).
Bitflüsterer schrieb:> Es wäre auch kontraproduktiv, Funktionen aus anderen Libraries in die> neu erzeugte Library zu übernehmen (im Sinne von kopieren). Nimm an, Du> möchtest mehrere Libraries verwenden, die aller wiederum eine bestimmte> Funktion aus einer dritten Library verwenden. Wenn jede davon eine Kopie> der Funktion enthält, wäre das ineffektiv.
Hmm dann habe ich das wohl etwas falsch ausgedrückt. Ich meinte wenn ich
die libk8055 compiliere dann wird ja auf die Funktionen der libusb
verwiesen. Diese ist wiederum im Quellcode der lib als include
eingebunden. Ich meinte daher das der Compiler von der lib mitgeteilt
bekommt welche er noch dazu linken muss. Das gleiche Problem ergibt sich
ja wenn ich das File in Eclipse compilieren will. Auch eclipse weiß
anscheinend nicht was und in welcher Reihenfolge er noch verlinken muss.
Das irritiert mich halt ein wenig. Wenn ich z.B. iostream include wird
in der ja auch weiter verlinkt ohne das ich die libs spezifisch angeben
muss.
Den Link werde ich mir mal ansehen. Hier gings jedoch um eine Lib die
ich nicht selbst erstellt hab sondern auf dem System installiert ist.
Gruß René
René S. schrieb:> Hmm dann habe ich das wohl etwas falsch ausgedrückt. Ich meinte wenn ich> die libk8055 compiliere dann wird ja auf die Funktionen der libusb> verwiesen.> Diese ist wiederum im Quellcode der lib als include> eingebunden. Ich meinte daher das der Compiler von der lib mitgeteilt> bekommt welche er noch dazu linken muss.
Wenn ich das versuche ganz neutral auszudrücken, dann verwendest Du die
Begriffe "verweisen" und "einbinden" nicht so wie es den realen
Vorgängen entspricht. Auch bekommt der Compiler nichts von einer Library
"mitgeteilt". Das Du das nicht ohne Weiteres weisst, ist an sich nicht
negativ, führt aber einfach zu falschen Schlussfolgerungen. Das ging uns
allen mal so, das wir theoretisch mögliche Zusammenhänge die wir für
bequem und sinnvoll hielten, irrigerweise für gegeben hielten, weil das
dem "gesunden Menschenverstand" entsprach.
Tatsache ist aber folgendes:
1. Eine include-Anweisung fügt den Inhalt der genannten Header-Datei in
den Programmtext ein. Nicht mehr nicht weniger. Ein "Verweis" ist damit
in keiner Hinsicht erzeugt, beschrieben, genannt oder Ähnliches.
Da in einer Header-Datei im wesentlichen nichts weiter als Deklarationen
stehen passt der Begriff "Verweis" auch nicht eigentlich.
Du wirst vielleicht schon wissen, das eine Deklaration erstmal nur
festlegt welche Rückgabewert und welche Parameter eine Funktion hat bzw.
welchen Typ eine Variable hat. Wenn Du darunter einen "Verweis"
verstehst, dann fügst Du eine Bedeutung hinzu die so nicht enthalten
ist.
Es kann irreführend sein, aber selbst wenn der Name der Header-Datei mit
dem Namen der Library-Datei übereinstimmt, dann nutzt der Compiler diese
Information nicht und gibt sie auch nicht an den Linker weiter.
Der Compiler nutzt die Deklarationen lediglich um vom Default-Typ
abweichende Funktionen bzgl. der Verwendung des Rückgabewertes und der
übergebenen Typen zu prüfen und passende Zuweisungs- bzw.
Stackoperationen zu erzeugen. Mehr nicht.
2. Beim compilieren wird nur und ausschliesslich eine einzige
Quelltext-Datei angeschaut. Der Compiler stellt keinen Zusammenhang
zwischen einer Header-Datei und einer evtl. dazugehörigen Library-Datei
her, wie er auch keinen Zusammenhang zu einer C-Datei herstellt, falls
die Header-Datei sich darauf bezieht. Der Bezug wird ausschliesslich im
Kopf des Programmierers hergestellt wenn er die Struktur seines
Programmes plant und erstellt. Insbesondere ist eine Library kein
aktives "Ding" das dem Compiler etwas mitteilt.
Der Compiler "sieht" ja letztlich auch, wie unter 1. erwähnt, auch
garnicht das er evtl. gerade Text liest, der aus einer Header-Datei
stammt. Er sieht nur Deklarationen. Nur C-Text.
Es wäre eine mehr philosophische Diskussion ob er das nicht doch tun
sollte. Der Punkt ist, das das automatische (also programmatische, denn
der Compiler ist ja auch ein Programm) Verhalten, wenn denn solche
Zusammenhänge hergestellt werden sollen, wesentlich komplexer und
fehleranfälliger wäre, weil neben dem Konzept das Du Dir auf dem Papier
vorher gemacht hast, die Deutung des Programmtextes durch den Compiler
dazu käme. Es ist auch wesentlich effizienter das Programm immer in
kleinen Häppchen zu behandeln.
3. Weder beim kompilieren oder beim Linken wird der Quelltext einer
verwendeten Library angeschaut. Andernfalls brächte man nämlich keine
Library, wenn man jedesmal den gesamten Quelltext aller beteiligten
Teile anschauen würde. Ausserdem eine Menge Speicher. Eine Library dient
ja gerade dazu schon fertige ("schon perfekte") Teile zur weiteren
Verwendung zusammenzufassen, ohne sie jedesmal neu "anschauen" zu
müssen.
Die Zusammenhänge sind eigentlich nicht wirklich kompliziert. Das wirst
Du schon begreifen, wenn Du mal ein wenig darüber liest und diskutierst.
Passe nur sehr darauf auf, was Du nur "unterstellst" weil es DIR
sinnvoll erscheinst und was dann tatsächlich ausdrücklich über das
kompilieren und linken gesagt wird.
Der wesentliche Begriff ist der der "Modularisierung" und der damit
angezielten Unabhängigkeit der Vorgänge der Kompiliation (in Bezug auf
mehrere C-Dateien untereinander) und des Linkens voneinander. Was die
Übersetzung und das Linken betrifft, sollen jedesmal in sich
geschlossene Vorgänge stattfinden, die in Bezug auf den Code ein
"sinnvolles" Teilergebnis ergeben.
Ein Objekt-File ist so ein Teil. Es enthält den ausführbaren Code der
C-Datei mit "Verweisen" (hier kommt das Wort sinnvoll vor) auf
Funktionen und Variablen die in anderen Objekt-Dateien "enthalten" sind
(in dem Sinne das sie den Code dafür und Speicherplatzreservierungen
enthalten).
Eine Library ist im wesentlichen auch so ein Objekt-File, wenn auch mit
etwas komplexerer "Verweisstruktur".
> Das gleiche Problem ergibt sich> ja wenn ich das File in Eclipse compilieren will. Auch eclipse weiß> anscheinend nicht was und in welcher Reihenfolge er noch verlinken muss.
Eclipse ist lediglich eine IDE - eine Benutzeroberfläche mit
komfortablem Editor. Über den Kompiliationsvorgang selbst weiß es
absolut nichts. Und es braucht darüber auch nichts zu wissen. Wichtig
ist, dass der Compiler und der Linker ihre notwendigen Informationen
erhalten.
Es ist zugegeben nicht offensichtlich, dass, obwohl man in Eclipse z.B.
die zum Projekt gehörenden Dateien angibt, nicht Eclipse compiliert und
linkt sondern es diese Eingaben nur nutzt um den Compiler etc.
aufzurufen.
Auch das Eclipse gewisse textuelle Zusammenhänge kennt, (etwa eine
Funktionsdefinition auffinden kann, wenn man mal nachgucken will)
bedeutet nicht, dass es den Programmtext in der selben Weise "versteht"
wie der Compiler. (Das ist zugegeben etwas schwammig ausgedrückt).
Eclipse nimmt den Text nur als Text, wie ein Mensch, der kein Spanisch
kann, wohl in der Lage ist, einzelne Wörter zu isolieren und im
Wörterbuch nachzuschlagen. Erst die Interpretation eines Satzes durch
den Menschen ergibt die Bedeutung. Die Wortfolge und auch die Folge der
Übersetzungen aus dem Wörterbuch enthält sie nicht.
> Das irritiert mich halt ein wenig. Wenn ich z.B. iostream include wird> in der ja auch weiter verlinkt ohne das ich die libs spezifisch angeben> muss.
iostream lässt sich nicht unmittelbar mit dem Fall einer selbst
erstellten (oder von einem Dritten erstellten Library) vergleichen. Sie
ist nämlich Teil des Sprachstandards und Compiler und Linker sind so
geschrieben, dass sie gerade diese Library ohne Dein Eingreifen, d.h.
ohne das Du sie ausdrücklicher im Linker-Befehl als Parameter angibst,
dazulinken.
> Den Link werde ich mir mal ansehen. Hier gings jedoch um eine Lib die> ich nicht selbst erstellt hab sondern auf dem System installiert ist.
Ich habe Dir den Link genannt, damit Du Dir den Vorgang anschaust und
evtl. die eine oder andere Schlussfolgerung ziehst. Libraries die Du
nicht selbst erstellt hast, wurden jedenfalls so oder so ähnlich (wenn
auch von jemand Anderem erstellt). Ihre allgemeinen Eigenschaften sind
dieselben, egal wer die Library erstellt.
Ich möchte Dir auch empfehlen unter den Stichworten "Compiler" und
"Linker" einmal in Wikipedia nachzulesen und auch den verlinkten
Begriffen nachzugehen. Wenn Du magst auch mal in der englischen
Wikipedia (die ich bei solchen Themen meist bevorzuge - warum will ich
hier mal nicht ausbreiten).
Danke für die ausführliche Erklärung. Muss mich wohl doch mal tiefer
damit befassen. Obwohl ich das ganze vor gut 20 Jahren mal gelernt habe
war mir das irgendwie nicht so bewusst. Kommt möglicherweise auch davon
das ich bisher mehr php und selten c programmiert habe. Wenn in c habe
ich bisher nur die Systembibliotheken genutzt.
Auf dem PC unter Windows in Delphi und Lazarus, aber auch nur wenig. Von
Pascal bin ich halt gewöhnt, wenn ich mit uses xyz was einbinde dann
holt der sich beim compilieren was er braucht.
Wollte das jetzt einfach mal unter C und Linux testen und merke das es
doch ned so einfach mal schnell geht. Ich denke das auch hier meine
Lesefaulheit Sonntag nachts die Ursache war. Ich hatte einfach den
Befehl übernommen den der Autor der lib auf der Sourceforge Seite
beschrieben hat... :)
Gruß René
René S. schrieb:> Wenn ich z.B. iostream include wird in der ja auch weiter verlinkt ohne> das ich die libs spezifisch angeben muss.
Das liegt aber nur daran, dass der Compiler das schon implizit in die
Linker-Kommandozeile mit aufnimmt, genauso wie die C-Standardlib und
noch ein paar andere wie z.B. die libsupc++ oder libgcc. Wenn du ihm
beim Linken den Kommandozeilenparameter -nostdlib mitgibst, tut er das
nicht, und du bekommst auch für alle Standardfunktionen die Meldung
"undefined reference", wenn du die Lib nicht explizit linkst.
@ René
Bitte. Gern geschehen.
Unter Einbeziehung Deiner Vorerfahrungen, sind mir Deine "intuitiven"
Annahmen nun etwas verständlicher. Ich hatte diesen Aspekt nicht sehr
ausgebreitet und nur kurz unter dem Stichwort "Philosophie" angerissen.
Ich habe selbst mal mit Pascal bzw. dem alten TurboPascal unter CP/M
angefangen. Ein anderer Fall ist z.B. Perl, dass ich recht oft verwende
(PHP kenne ich nur vom Hörensagen :-) )
Es gibt da schon Unterschiede. Das alte TurboPascal z.B. hatte eine
monolithischen Struktur: One For All.
Perl (ich denke in diesem Zusammenhang ist PHP nicht wirklich anders),
kriegt ein "use" und dann war es das.
Theoretisch wäre so eine "Library-Intelligenz" (was einen Teil Deiner
Frage betrifft) auch mit C möglich (und ich meine mich an einige
C-Varianten z.B. für MSDOS oder CP/M zu erinnern, die das auch so
machten. Allerdings ist das auch nicht ganz unproblematisch. Ich hatte
das oben schon kurz angerissen, will das hier aber nicht weiter
ausbreiten.
Klar: Wenn man eigentlich nur schnell mal was probieren wollte, dann ist
das zunächst problematisch. Aber jedenfalls ist das alles nicht wirklich
kompliziert. Und wenn Du mal die Wikipedia-Artikel gelesen hast und
vielleicht noch einige Aspekte hier nachfragst, dann wirst Du das schon
recht schnell verinnerlichen.
Viel Erfolg noch.
Bitflüsterer schrieb:> Theoretisch wäre so eine "Library-Intelligenz" (was einen Teil Deiner> Frage betrifft) auch mit C möglich
Nein, sogar praktisch. Es gibt C-Compiler, die über ein pragma einen
Kommentar in Objektdateien unterbringen, der wiederum vom Linker
ausgewertet wird und dafür sorgt, daß die so benannte Library quasi
"automatisch" gelinkt wird.
Bei dieser Vorgehensweise genügt es also tatsächlich, eine Headerdatei
einzubinden (sofern diese den pragma-Kommentar enthält) und der Rest
passiert von alleine.
Aber das ist halt eine herstellerspezifische Vorgehensweise, und weil
sie von Microsoft stammt, entweder verpönt oder möglicherweise
patentrechtlich unterdrückt.