lib programmieren

Message
Author
Bodo Schulz

lib programmieren

#1 Post by Bodo Schulz »

Moin Moin! <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">

Sagt mal, gibt es irgendwo ein HowTo, in dem einfach beschrieben steht, wie man eine eigene Lib programmiert und diese (logischerweise) auch in eigene, externe Programme einbindet?
Ich hab mal eine unter dem guten alten Amiga erstellt, aber das ist ja schon ewigkeiten her ... ;)
Spezielle geht es mir darum, genaue Einsprungfunktionen zu definieren, die ich von extern nutzen kann und (natürlcih) die lib erstmal zum laufen zu bewegen ;)

Bodo

Sebastian Ude

Re: lib programmieren

#2 Post by Sebastian Ude »

Folgendes Beispiel, eine (shared) lib mit nur einer Funktion:

/* Anfang test.c */
#include <stdio.h>

void hellow(void)
{
printf("Hello World
");
}
/* Ende test.c */

/* Anfang test.h */
void hellow(void);
/* Ende test.h */

gcc -c test.c
gcc -shared -o libtestlib.so test.o

So, jetzt wirds spannend <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">.

/* Anfang libtest.c */
#include "test.h"
int main()
{
hellow(); /* Aus unserer lib */
return 0;
}
/* Ende libtest.c */

gcc -L. -o libtest libtest.c -ltestlib

export LD_LIBRARY_PATH=$PWD
./libtest
Hello World

In der Tat, es geht. Ich hoffe du konntest diese Schritte nachvollziehen...

Bodo Schulz

Re: lib programmieren

#3 Post by Bodo Schulz »

Danke!! <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">
Ich probiers gleich mal, wenn ich wieder zu Hause bin und diese dämliche Migräne los bin!

Bodo

Ozi

Re: lib programmieren

#4 Post by Ozi »

Hi,

wow, das hab ich auch kapiert. Sollte ich vielleicht auch mal ausprobieren.

cu

Oliver

bakunin
Posts: 597
Joined: 16. Aug 1999 6:44
Location: Lorsch (Südhessen)
Contact:

Re: lib programmieren

#5 Post by bakunin »

Hi!

Ich bin jetzt ein wenig verwirrt, denn ich dachte, für Bibliotheken müsste man PIC (Position Independent Code) verwenden, wozu man die Option -fPIC angeben muss. Ok, ich habe in die gcc-Doku geschaut und in der Tat scheint man PIC nicht zwingend zu benötigen, aber dann frage ich mich, was die Vor-/Nachteile von PIC sind. Weiß jemand etwas darüber?

Cheers,
Wolfgang

Descartes

Re: lib programmieren

#6 Post by Descartes »

<a href="http://mail.gnu.org/pipermail/libtool/1 ... 03566.html" target="_blank"><!--auto-->http://mail.gnu.org/pipermail/libtool/1 ... <!--auto-->
<blockquote><hr>

> I have to admit that it makes perfect sense to me that you can't link
> non-pic object files in what will become a shared object file. I mean,
> if you could, there would be no need for the -fPIC option.
> Generally, non-pic code is faster than pic code anyway.
> Why would anybody use -fPIC if it's not needed for a shared object?

In an executable, non-pic code is faster. However, a shared library
needs to be position independent. You can build a shared library with
non-pic code, but that just means that the dynamic linker has to do
much more work to load the code at whatever address it should go to.
Specifically, the dynamic linker has to resolve all the relocations at
run time, every time the program is run. Thus, in a shared library,
pic code is faster. That's why pic code was invented.

> I mean, if you could, there would be no need for the -fPIC option.
> Generally, non-pic code is faster than pic code anyway. Why would
> anybody use -fPIC if it's not needed for a shared object?

A good reason I can think of is that relocation would prevent code
pages from being shared, if they happen to be mapped onto different
addresses in different processes' address spaces.
<hr></blockquote>

Descartes

Re: lib programmieren

#7 Post by Descartes »

Auf manchen Plattformen scheint es möglich zu sein, funktionierende shared libraries auch ohne die Compiler-Option -fPIC zu erzeugen. Mindestens auf der ARM Plattform funktioniert ein solches vorgehen allerdings anscheinend nicht.

Da aber die Programming-Library-HOWTO schreibt, dass man zum erzeugen einer shared library den Library Quellcode mit <b>gcc -fPIC -c test.c</b> kompilieren und mit <b>gcc -shared -o libtestlib.so test.o</b> linken soll, denke ich einfach mal dass dies die korrektere Vorgehensweise ist.

How to build libraries?
<a href="http://lists.samba.org/pipermail/linux/ ... 00318.html" target="_blank"><!--auto-->http://lists.samba.org/pipermail/linux/ ... <!--auto-->

[<!--no-->ARM<!--no-->] about shared libraries
<a href="http://lists.arm.linux.org.uk/pipermail ... 00221.html" target="_blank"><!--auto-->http://lists.arm.linux.org.uk/pipermail ... <!--auto-->

Program-Library-HOWTO
<a href="http://www.linuxdoc.org/HOWTO/Program-L ... html#AEN79" target="_blank"><!--auto-->http://www.linuxdoc.org/HOWTO/Program-L ... <!--auto-->

bakunin
Posts: 597
Joined: 16. Aug 1999 6:44
Location: Lorsch (Südhessen)
Contact:

Re: lib programmieren

#8 Post by bakunin »

Hi!

Vielen Dank für die Erklärung, und natürlich auch für die Links.

Cheers,
Wolfgang

User avatar
heinrich
Posts: 219
Joined: 22. Sep 1999 11:22
Location: N49.137 E8.544

Re: lib programmieren

#9 Post by heinrich »

<font size="4">Quellcodes</font><!--4--> wie bereits oben geposted.

<font size="3">test.c</font><!--3--><font face="Courier New">
// Quellcode unserer Lib

void hellow(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;printf("Hello World\<!--no-->n");
}
</font><!--fixed-->

<font size="3">test.h</font><!--3--><font face="Courier New">
// liste der exportierten funktionen

void hellow(void);
</font><!--fixed-->

<font size="3">libtest.c </font><!--3--><font face="Courier New">
// testprogramm fuer unsere library
#include "test.h"

int main(int argc, char** argv)
{
&nbsp;&nbsp;&nbsp;&nbsp;hellow(); /* Aus unserer lib */
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}
</font><!--fixed-->


<font size="4">shared library:</font><!--4-->

<font size="3">Lib erstellen:</font><!--3-->
<font size="2">Linux:</font><!--2--><font face="Courier New">
$ gcc -fPIC -DPIC -c test.c
$ gcc -shared -o libtestlib.so.1.0 -Wl,-soname,libtestlib.so.1 test.o
$ ln -s libfoo.so.1.0 libfoo.so.1
$ ln -s libfoo.so.1 libfoo.so</font><!--fixed-->

<font size="2">Solaris:</font><!--2--><font face="Courier New">
$ gcc -fPIC -DPIC -c test.c
$ ld -G -o libtestlib.so test.o</font><!--fixed-->

<font size="2">Irix:</font><!--2--><font face="Courier New">
$ gcc -fPIC -DPIC -c test.c
$ ld -shared -o libtestlib.so test.o</font><!--fixed-->

<font size="3">Lib benutzen:</font><!--3--><font face="Courier New">
$ export LD_LIBRARY_PATH=.:${LD_LIBRARY_PATH}
$ gcc -L. -o libtest libtest.c -ltestlib</font><!--fixed-->

<font size="4">static library:</font><!--4-->
<font size="3">Lib erstellen:</font><!--3--><font face="Courier New">
$ gcc -fPIC -DPIC -c test.c
$ ar rcs libtest-static.a test.o</font><!--fixed-->

<font size="3">Lib benutzen:</font><!--3--><font face="Courier New">
$ gcc -L. -o libtest libtest.c -ltestlib-static</font><!--fixed-->

<font size="4">Referenz:</font><!--4-->
Program-Library-HOWTO
<a href="http://www.linuxdoc.org/HOWTO/Program-L ... html#AEN79" target="_blank"><!--auto-->http://www.linuxdoc.org/HOWTO/Program-L ... <!--auto-->

thedodger
Posts: 26
Joined: 07. Feb 2001 13:39
Contact:

Re: lib programmieren

#10 Post by thedodger »

Also, ich habe mir eine lib erzeugt, was auch wunderbar funktioniert hat. Danke schon mal ...
aaaber ... ich bekomme sie einfach nicht zu meinem testprojekt gelinkt! :(((

die einzige Fehlermeldung, die ich erhalte, ist folgende:

/usr/i486-suse-linux/bin/ld: cannot find -lums4sql
collect2: ld returned 1 exit status

und ich habe LD_LIBRARY_PATH entsprechend angepasst ... <img src="http://www.pl-forum.de/UltraBoard/Images/Sad.gif" border="0" align="middle">

hat jemand eine Idee, die mir helfen könnte?

Bodo

Sebastian Ude

Re: lib programmieren

#11 Post by Sebastian Ude »

LD_LIBRARY_PATH muss nur während der Laufzeit gesetzt sein, damit die Library gefunden wird.
Alternativ kann man auch das jeweilige Verzeichnis in die /etc/ld.so.conf eintragen und ein "ldconfig" machen.

Beim compilieren ist es aber einzig und allein wichtig, dass man dem gcc mit der -L-Option das Verzeichnis angibt, wo die eigene Library zu finden ist.

Ich hatte es ja auch in meinem Beispiel so gemacht:

>gcc -L. -o libtest libtest.c -ltestlib

Dabei ist das '-L.' wichtig !
In diesem Fall lag die Library ja im aktuellen Verzeichnis, aber nur durch das '-L.' sucht gcc die Library auch dort.
Ohne das '-L.' hätte ich genau die selbe Fehlermeldung gekrigt wie du jetzt.
Alternativ könntest du die Lib einfach nach /usr/lib kopieren, dann bliebe dir die Angabe der '-L'-Option erspart.

Auch wichtig ist der Name der Library.
Sie muss lib[name].so oder lib[name].a bei einer statischen Library heissen.
Sprich, wenn du '-lums4sql' angibst, muss die Datei libums4sql.so heissen !

thedodger
Posts: 26
Joined: 07. Feb 2001 13:39
Contact:

Re: lib programmieren

#12 Post by thedodger »

> Auch wichtig ist der Name der Library.
> Sie muss lib[name].so oder lib[name].a bei einer statischen Library heissen.
> Sprich, wenn du '-lums4sql' angibst, muss die Datei libums4sql.so heissen !

Das war schon mal der richtige anhaltspunkt ... damit scheint der erste Fehler verschwunden zu sein ... dafür hab ich jetzt mehr dazu bekommen ;-/

was sagt einem das hier: ??

/tmp/ccqKrcHG.o: In function `main':
/tmp/ccqKrcHG.o(.text+0x6e): undefined reference to `umsLogin(bsString, bsString)'
/tmp/ccqKrcHG.o(.text+0xa9): undefined reference to `umsReadMsg(base *, bsString)'
/tmp/ccqKrcHG.o(.text+0xef): undefined reference to `umsLogout(base *)'

[ diese funktionen will ich aus der lib heraus benutzen ]

./libums4sql.so: undefined reference to `base'
./libums4sql.so: undefined reference to `umsDatabase::disconnect(BASE *)'
./libums4sql.so: undefined reference to `umsQuery::Add(bsString)'
./libums4sql.so: undefined reference to `umsDatabase::umsDatabase(void)'
./libums4sql.so: undefined reference to `umsDatabase::connected(void)'
./libums4sql.so: undefined reference to `umsQuery::Clear(void)'
./libums4sql.so: undefined reference to `BASE::getError(void)'
./libums4sql.so: undefined reference to `BASE::setError(bsString)'
./libums4sql.so: undefined reference to `umsDatabase::connect(void)'
./libums4sql.so: undefined reference to `umsQuery::FieldbyName(bsString)'
./libums4sql.so: undefined reference to `umsQuery::Open(pg_conn *)'
./libums4sql.so: undefined reference to `umsQuery::isEmpty(void)'
./libums4sql.so: undefined reference to `umsDatabase::getLastError(void)'
./libums4sql.so: undefined reference to `umsQuery::umsQuery(void)'

[und das sind Klassen, die ich in der lib intern benutze ...]

Sebastian Ude

Re: lib programmieren

#13 Post by Sebastian Ude »

Hm ... schwer zu sagen was da schief gegangen ist.

Du hast schon Prototypen für alle "externen" (also nicht nur intern benutzen) Funktionen der libs erstellt, oder etwa nicht ?
Am besten eine Header-File "ums4sql.h" erstellen, und dort die ganzen Prototypen setzen, und "ums4sql.h" dann von allen Programmen die die Lib benutzen includen.

Was passiert denn, wenn du nicht gegen die Libs linkst, sondern einfach mal alle Object-Files (*.o) aus denen du die Lib erstellt hast statisch dazulinkst ?

Sebastian Ude

Re: lib programmieren

#14 Post by Sebastian Ude »

Was auch noch plausibel wäre:

Du hast die Library doch nicht etwa mit strip aller Symbole beraubt ?!

bakunin
Posts: 597
Joined: 16. Aug 1999 6:44
Location: Lorsch (Südhessen)
Contact:

Re: lib programmieren

#15 Post by bakunin »

Hi!

Wichtig ist außerdem, dass die Bibliothek beim Compileraufruf _nach_ den Objektdateien angegeben wird.

Also immer "gcc -o foo foo.o -lbar" und nicht "gcc -o foo -lbar foo.o".

Cheers,
Wolfgang

Post Reply