Forum: Compiler & IDEs __attribute__( ( alias( "."))) funktioniert nicht


von Martin F. (martinf)


Angehängte Dateien:

Lesenswert?

hey,

hab folgendes Problem:
Ich brauch ne polymorphe Funktion, die Stringparameter aus dem Daten- 
und Programmbereich unterscheiden kann.
1
void foo( const char* const _cstrText) { ... }
und
1
typedef char __attribute__( ( __progmem__))  prog_char;
2
void foo( const prog_char* const _cstrText) { ... }
funktioniert nicht, da beide Typgleich sind.



Also hab ich mir einen neuen Typ erstellt:
1
struct __attribute__( ( __progmem__)) __SProgChar {
2
  char __dummy;
3
};
4
typedef struct __SProgChar pchar_t;

Um nun einen String (hier: abc mit Inhalt "test") im Programmspeicher 
abzulegen, benutze ich
1
__asm(
2
  "\n\t .text"
3
  "\n\t .align 2"
4
  "\n\t .global abc" 
5
  "\n\t abc: .asciz \"test\""
6
);
7
extern const prog_char* abc[];
8
extern pchar_t identifier[sizeof( "test")] __attribute__( ( alias( "abc")));

Obwohl abc im asm-Teil global und im cpp-Teil extern deklariert ist, 
bekomme ich beim compilieren folgende Fehlermeldung in der letzten 
Zeile:
1
error: 'identifier' aliased to undefined symbol 'abc'

Ist das ein Bug oder überseh ich was?

mfg Martin

von Stefan E. (sternst)


Lesenswert?

Das Alias-Target muss in der selben Datei definiert sein. abc ist aber 
nur deklariert, nicht definiert. Und die Symbol-Definition im asm-Teil 
wird vom Compiler natürlich nicht als solches erkannt (erst später dann 
vom Assembler). Wozu brauchst du das Alias überhaupt? Deklariere doch 
abc gleich in dem von dir gewünschten Typ.

Außerdem fehlt im dem asm-Teil auch noch ein align hinter den Daten. 
Lass das Platzieren der Daten im Flash doch den Compiler erledigen. 
Definiere doch einfach in einer anderen Datei abc als normalen 
Flash-String.

von Martin F. (martinf)


Lesenswert?

Wie gesagt, ich kann den String nicht per prog_char ablegen, da 
prog_char typgleich mit char ist und dann die Polymorphie nicht mehr 
funktioniert.

Ich hab mir ne andere Möglichkeit überlegt, mit der ich recht zufrieden 
bin:
1
#define CreatePGMStringDecl( identifier) \
2
  extern const prog_char identifier##_p[]; \
3
  extern const pchar_t identifier[]
4
5
#define CreatePGMStringDef( identifier, value) \
6
  const prog_char identifier##_p[] = value; \
7
  extern const pchar_t identifier[sizeof( identifier##_p)] __attribute__( ( alias( #identifier"_p")))

in der Headerdatei:
1
CreatePGMStringDecl( abc);

in der Quelldatei:
1
CreatePGMStringDef( abc, "test");

Somit hab ich jetzt zwei Arrays aber trotzdem nur einen Speicherort.
Was die Definition im asm-Teil angeht, die der Compiler nicht erkennt, 
hast du recht. Jetzt funktioniert das alias nämlich ohne Probleme.

Vielen Dank für den Tipp

von Stefan E. (sternst)


Lesenswert?

Martin Freund schrieb:
> Wie gesagt, ich kann den String nicht per prog_char ablegen, da
> prog_char typgleich mit char ist und dann die Polymorphie nicht mehr
> funktioniert.

Nicht? Du machst es doch mit deiner Lösung jetzt auch.

Mein Vorschlag war halt nur etwas simpler gestrickt.

FlashData.cpp:
1
char abc[] PROGMEM = "test";
Hier werden die Daten nur ins Flash gepackt, und sonst nichts weiter 
gemacht.


SomeOtherFile.cpp oder FlashData.h:
1
extern const pchar_t abc[];
Hier kannst du die Daten dann mit dem gewünschten Typ verwenden.

von Martin F. (martinf)


Lesenswert?

>> Wie gesagt, ich kann den String nicht per prog_char ablegen, da
>> prog_char typgleich mit char ist und dann die Polymorphie nicht mehr
>> funktioniert.
>
> Nicht? Du machst es doch mit deiner Lösung jetzt auch.

Ich leg ihn jetzt zwar per prog_char ab, aber als abc_p. Auf den 
alternativen Typ greif ich ohne den Zusatz "_p" zu.

Wenn ichs so mach
1
> char abc[] PROGMEM = "test";
2
> extern const pchar_t abc[];
dann bekomm ich
1
error: conflicting declaration 'const pchar_t abc []'
2
error: 'abc' has a previous declaration as 'char abc [5]'

Genau deswegen brauch ich ein alias.

von Stefan E. (sternst)


Lesenswert?

Ich habe ja auch nicht ohne Grund "andere Datei" geschrieben. Und ich 
dachte auch mein Beispiel würde das verdeutlichen.

von Martin F. (martinf)


Lesenswert?

Ahhh, hab vor Eifer nicht dran gedacht dass die Trennung zwischen 
Deklaration/Definition jetzt verpflichtend ist.
Vielen Dank für deine Hilfe.

von Stefan E. (sternst)


Lesenswert?

Martin Freund schrieb:
> Ahhh, hab vor Eifer nicht dran gedacht dass die Trennung zwischen
> Deklaration/Definition jetzt verpflichtend ist.

Wenn beides unterschiedliche Typen haben soll, dann schon. ;-)

Versteh mich nicht falsch, ich will dich zu nichts überreden. Wenn du 
eine für dich funktionierenden Lösung hast, dann ist es ja ok. Ich 
wollte nur darauf hinweisen, dass der Alias nicht zwingend notwendig 
ist.

von Martin F. (martinf)


Lesenswert?

Deine Lösung ist definitv sauberer. Wenn ichs per asm mach, erscheinen 
die Strings nicht in der Exporttabelle von avr-nm. Und wenn ichs mit nem 
alias mach, bekomm ich doppelte Einträge. Ich hab auf jeden Fall was 
dazu gelernt ;)

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.