Forum: Compiler & IDEs undefined reference mit "extern inline" in header


von kruemeltee (Gast)


Lesenswert?

Ich versuche gerade ezfb ( http://www.akrobiz.com/ezfb/ , eine 
Framebuffer-Lib) in  meinem eigenen Projekt zu compilieren, stosse da 
aber auf ein Problem.

Die Demos lassen sich ohne weiteres von meinem Host-GCC compilieren.
Der Cross-Compiler, der ezfb compilieren soll ist ein GCC für ARM.
Der compiliert auch ohne Warnungen mit -Wall durch, nur linken kann er 
nicht. Allerdings macht es keinen Unterschied ob ich den Host oder den 
Cross-Compiler im Makefile einsetze.

Hier die Fehlermeldungen:
1
...
2
ezfb_bmp.c:1205: undefined reference to `bmp_is_same_size'
3
ezfb_bmp.c:1733: undefined reference to `ezfb_get_g_from_rgb'
4
ezfb_bmp.c:1736: undefined reference to `ezfb_get_r_from_rgb'
5
ezfb_bmp.c:1760: undefined reference to `ezfb_get_b_from_rgb'
6
...
7
collect2: ld returned 1 exit status
8
...
Das sind noch ein paar mehr, aber alle Funktionen, die der Linker nicht 
findet sind in einer Header-Datei, die auch eingebunden wird.

Die Funktionen sehen da so aus:
1
extern inline u_short ezfb_get_r_from_rgb(struct ezfb* fb, u_int rgb)
2
{
3
    switch(fb->Var.bits_per_pixel)
4
    {
5
        default:
6
        case  1:
7
        case  2:
8
        case  4: return 0;
9
        //--------------------------------------------------------------------
10
        case  8: return (int)(255 * (rgb & 0xe0) / 224.0); // based on ezfb_set_cmap_reduction();
11
        //--------------------------------------------------------------------
12
        case 15:     // returns a scaled char ie: fb->Var.red.length bits to 8 bits
13
        case 16: {   // by adding the top msb's to the otherwise zeros at the low end
14
                      u_char c = (((rgb << EZFB_BITS_IN_CHAR) >> fb->colors.offset_plus_length_red) & fb->colors.bit_mask_red);
15
                      return c |= ((c & ~((1 << fb->Var.red.length) - 1)) >> fb->Var.red.length);
16
                 }   // off is off and full on is 255
17
        //--------------------------------------------------------------------
18
        case 24:
19
        case 32: return (rgb >> fb->Var.red.offset) & fb->colors.bit_mask_red;
20
    }
21
}
(Nur eine um zu sehen, wie genau die gemacht wurden.

Dass die in einer Header-Datei stehen, wundert mich ein wenig, aber die 
Demos compilieren ja auch ohne Fehler/Warnungen durch. Daher wird das 
schon seine Richtigkeit haben, oder?

Ich hoffe jemand von euch kann mir dabei helfen, das zu lösen :)

von Karl H. (kbuchegg)


Lesenswert?

ersetze das 'extern' durch 'static'


(Da hat wieder mal jemand nicht begriffen, was inline eigentlich macht, 
bzw. darüber nachgedacht, was der Compiler da machen soll. Auch das 
Schlüsselwort 'extern' hat den Progammierer anscheinend verwirrt. Die 
Kombination 'extern inline' ist so ziemlich die unsinnigste Kombination, 
die man sich vorstellen kann)

von kruemeltee (Gast)


Lesenswert?

Das habe ich jetzt gemacht und der Linker findets auch. Allerdings:
1
warning: 'ezfb_get_b_from_rgb' is static but used in inline function 'ezfb_get_b_from_pixel' which is not static
Was heisst nun das? Ich glaube nicht, dass das auf Dauer so 
funktionieren wird, heisst nicht umsonst Warnung :D

von Karl H. (kbuchegg)


Lesenswert?

kruemeltee schrieb:

> is static but used in inline function 'ezfb_get_b_from_pixel'

'ezfb_get_b_from_pixel' ist selber wieder eine inline Funktion.
Schreib der auch noch ein static davor.

von kruemeltee (Gast)


Lesenswert?

>'ezfb_get_b_from_pixel' ist selber wieder eine inline Funktion.
>Schreib der auch noch ein static davor.
Omg, danke... Da war doch was mit den vielen Bäumen vor dem Wald oder so 
;)

Ich dachte anhand der Meldung, dass sich die Funktionen umgekehrt herum 
aufrufen, konnte aber z.B. in der, die ich oben gepostet habe, das nicht 
finden. Darum war ich etwas sehr verwirrt.

Vielen Dank für deine Hilfe!

von Simon K. (simon) Benutzerseite


Lesenswert?

Bezüglich *extern inline*: Warum wird das überhaupt zugelassen? Inline 
verlangt doch, dass dem Compiler in der Compilation Unit der gesamte 
Funktionscode vorliegt. Extern hingegen sagt dem Compiler ja 
(gegensätzlich), dass es die Funktion gibt, nur dass er keinen Code zu 
sehen bekommt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

extern inline stellt ihm laut C99 frei, welche der beiden Definitionen
(die beide vorliegen müssen) er dann benutzt.

von Karl H. (kbuchegg)


Lesenswert?

Jörg Wunsch schrieb:
> extern inline stellt ihm laut C99 frei, welche der beiden Definitionen
> (die beide vorliegen müssen) er dann benutzt.

In dem Fall muss es dann aber auch irgendwo eine tatsächliche 
Implementierung geben. Offenbar gabs die aber in diesem Projekt nicht 
und der Compiler hat sich gegen das inlineing entschieden.

von Simon K. (simon) Benutzerseite


Lesenswert?

Oder kruemeltee hat vergessen die Library einzutragen im Makefile?

von Pothead (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> extern inline stellt ihm laut C99 frei, welche der beiden Definitionen
> (die beide vorliegen müssen) er dann benutzt.

Doll. Man lernt nie aus... Jörg, kannst du ein Minimalbeispiel 
konstruieren? So richtig sinnig scheint mir das nicht zu sein.

von Pothead (Gast)


Lesenswert?

Ich versuchs mal selber...etwa so?

eins.c:
1
include "eins.h"
2
3
void baz(void)
4
{
5
   foo();  // "inlining"?
6
}
7
8
inline void 
9
foo(void)
10
{
11
}

eins.h:
1
extern inline void foo(void);

zwei.c:
1
#include "eins.h"
2
3
void
4
bar(void)
5
{
6
   foo();  // kein "inlining"?
7
}

von Simon K. (simon) Benutzerseite


Lesenswert?

Ich würd eher sagen so:


zwei.c
1
#include "zwei.h"
2
3
/* Nicht-geinlined */
4
int zwei(int A)
5
{
6
    return A*A;
7
}

zwei.h
1
/* Geinlined */
2
extern inline int zwei(int A)
3
{
4
    return A*A;
5
}

eins.c
1
#include "zwei.h"
2
3
void eins(void)
4
{
5
    /* Aufruf kann entweder geinlined oder gelinkt sein */
6
    zwei();
7
}

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.