PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : eine struct als Parameter an Funktion übergeben...?



HaWe
02.12.2018, 13:12
hallo,
ich habe eine struct


typedef struct {
int foo;
char bas;
} list;

list mList00;

// display Funktion
void displayMenulist(list mList) {
Serial.println(mList.foo);
Serial.println(mList.bas);
}

//

und möchte nun mList00 zunächst "by value" an diese display Funktion übergeben



mList00.foo=100;
mList00.bas=3;

displayMenulist(mList00); // editiert

geht aber nicht, ich kriege immer den error


exit status 1
variable or field 'displayMenulist' declared void

wie macht man es richtig?

Holomino
02.12.2018, 13:59
"displayMenulist(list mList00);"

Muss man da beim Arduino beim Aufruf der Funktion den Typnamen noch mal vor den Argumentewert setzen?
Warum?

HaWe
02.12.2018, 14:12
das war ein typo beim nachträglichen editieren,
nein, beim Aufruf nicht mehr.

Holomino
02.12.2018, 15:44
https://www.reddit.com/r/arduino/comments/4isgjf/variable_or_field_xxxx_declared_void/

Kann es sein, dass Deine "list"-Deklaration nicht weit genug oben im Sketch steht und die Prototypen vom Compiler davor eingefügt werden?

HaWe
02.12.2018, 16:08
hmm... kann ich nicht erkennen, siehst du mehr als ich?

Hier ist der Testcode:



/*
*
*********** This code is for the ESP8266 ***********
*
****** ESP_ssd1306_128x64_I2C demo display *********
*
* using ESP_SSD1306 Adafruit library
* for a ssd1306 OLED Display with the ESP8266 board
*
*********** This code is for the ESP8266 ***********
*
*/


// i2c
#include <Wire.h> // Incl I2C comm, but needed for not getting compile error
#define ESPSDA D2 // defaults
#define ESPSCL D1 //

// TFT
#include <ESP_SSD1306.h> // Modification of Adafruit_SSD1306 for ESP8266 compatibility
#include <Adafruit_GFX.h> // Needs a little change in original Adafruit library (See README.txt file)
#include <Fonts/FreeSans12pt7b.h> //
#include <Fonts/FreeSansBold12pt7b.h> //
#include <Fonts/FreeSans9pt7b.h> //
#include <Fonts/FreeMono12pt7b.h> //
#include <Fonts/FreeMono9pt7b.h>
// Pin definitions
#define OLED_RESET 10 // GPIO10=D12 Pin RESET signal (virtual)

ESP_SSD1306 display(OLED_RESET); // FOR I2C

/*
#include <ButtonClass.h>
tButton btnup;
tButton btnle;
tButton btnri;
*/



//----------------------------------------------------------------------------
// OLED dashboard
//----------------------------------------------------------------------------


byte MAXMODE=12;

void dashboard(byte mode) {
if(mode>MAXMODE ) { mode=0; }

display.clearDisplay();
display.setFont();


display.display();
display.setFont();
}

//----------------------------------------------------------------------------
// menu list
//----------------------------------------------------------------------------


char LINELEN = 8;
char LINENUM = 4;

typedef struct {
char line[8][20] = {"line0_67 9012345678" ,"line1_6" ,"line2_67" ,
"line3_6789012345678" ,"line4_6789012345678" ,"line5_6789012345678" ,
"line6_6789012345678" ,"line7_6789012345678" };
char act=0, top=0, btm=top+LINENUM;
char subl[12]=" ";
} list;

list mList00;


void strcpysubl(char * dest, char * source, char pos) {
byte l;
memset(dest,' ',sizeof(dest));
dest[12]=0;
strncpy( dest+1, source+pos, LINELEN );
if(strlen(source)>(8+pos) ) dest[9] = '~' ;
else for( l=strlen(dest); l<=9; l++) dest[l]=' ';
dest[10] = '>';
dest[11] = 0;
}


void displayMenulist(list mList) {
int8_t start;
byte l;

if(mList.act>LINENUM) start=mList.act;
else start=0;

for(byte i=0+start; i<5+start; i++) {
strcpysubl( mList.subl, mList.line[i], 0);

if(i==mList.act) {
//display.setTextColor(BLACK, WHITE);
mList.subl[0]='>';
}
//else display.setTextColor(WHITE);
l=10 + i*13;
display.setCursor( 0, l); display.print(mList.subl);
Serial.println(mList.subl);
display.display();
}

}




void setup(void)
{
// Start Serial

Serial.begin(115200);
delay(2000); // wait for Serial()

// Start Wire (SDA, SCL)
Wire.begin(ESPSDA,ESPSCL); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// SSD1306 Init
display.begin(SSD1306_SWITCHCAPVCC); // Switch OLED
display.setRotation(2);
display.clearDisplay(); // Clear the buffer.

// text display tests
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Hello, world!");
display.display();

delay(1000);
display.clearDisplay();
display.display();

for(byte i=0; i<8; i++) { Serial.println(mList00.line[i]); }

Serial.print("act="); Serial.println((byte)mList00.act);

display.setFont(&FreeMono9pt7b); // h=13.10pt
displayMenulist(mList00);

delay(2000);

}


void loop() {

}

Moppi
02.12.2018, 16:19
Vom Prinzip scheints richtig zu sein.

Für das ABER, habe ich das hier gefunden. Dort gibt es dasselbe Problem mit "variable or field '......' declared void (https://forum.arduino.cc/index.php?PHPSESSID=kscck02ndlplo5sa249no9pbq5&topic=381325.msg2629217#msg2629217)"und auch eine Lösung dafür: https://forum.arduino.cc/index.php?topic=381325.0

MfG

HaWe
02.12.2018, 16:53
verstehe ich nicht, was soll ich da jetzt wo hinzufügen?

- - - Aktualisiert - - -

aaah...
ich glaube, ich habs:
es klappt,
man muss die struct ganz oben definieren, vor allen #includes etc.

danke!! 8)

Moppi
02.12.2018, 17:23
Keine Ahnung, kenne mich doch damit selber nicht aus. Musst Du mal lesen und mit Deinen Sachen vergleichen.

HaWe
02.12.2018, 17:47
ja, es klappt, danke!

Moppi
02.12.2018, 17:58
Prima, freut mich! :)

Holomino
02.12.2018, 18:29
Wenn Du an irgendeiner Stelle in C eine Funktion aufrufst, muss der Compiler nicht wissen, was in der Funktion an Code steht. Er muss aber den Funktionsrumpf (Name, Parameter, Rückgabewert) für die Codeauflösung kennen. Steht die eigentliche Funktion weiter unten hinter dem Aufruf, erledigt man diese Bekanntmachung üblicherweise über eine Funktionsdeklaration (Vorwärtsreferenz):

void DoSomething(int hellIsFrozen); //The forward reference (function header with ending semicolon)

void main(){DoSomething(42);} //The call
void DoSomething(int hellIsFrozen){while(hellIsFrozen);} //The function

Typischer Halbblödenautomatismus: Um die manuelle Deklaration von Vorwärtsreferenzen zu vermeiden, legt der Arduino-Compiler ungefragt für jede Funktion eine Deklaration unterhalb der #includes an. Dass eine dieser Deklarationen einen Datentyp verwendet, der erst danach im Code deklariert wurde, scheint dabei in Kauf genommen zu werden, ebenso wie die nicht reproduzierbare Fehlermeldung, die naturgemäß nur auf eine vom Compiler erzeugte Codezeile (genau auf die automatisch generierte Vorwärtsreferenzzeile, also quasi für den User nicht nachvollziehbar) verweisen kann.

Ich will das Arduino-Konzept nicht allgemein schlecht reden. Aber DAS ist wirklich dilletantisch gemacht.

HaWe
02.12.2018, 18:38
ja, genau:
es lag nicht an der Funktion, die stand an der richtigen Stelle.
auch die struct war ursprünglich schon an der richtigen Stelle.
Es lag am temp. generierten Arduino-Zwischencode.
Muss man mal bei github als issue melden.

HaWe
03.12.2018, 09:19
update:
die Ursache muss doch woanders gelegen haben, nicht an der gezeigten Reihenfolge sondern evtl bei einer ganz anderen Funktion im Originalcode, die mit diesem error direkt nichts zu tun hatte - lässt sich z.Zt aber nicht lokalisieren.

HaWe
03.12.2018, 13:53
update 2:
es lag doch an einem temporären prototype, das aber erst durch eine weitere - dazwischenliegende - Funktion kritisch wurde, selbst wenn wie in diesem Fall jene zusätzliche Funktion noch nicht einmal genutzt wurde:

https://github.com/arduino/Arduino/issues/8257?_pjax=%23js-repo-pjax-container#issuecomment-443704817

Nichtsdestotrotz scheint die neueste IDE 1.9.x diesen Fehler nicht mehr zu erzeugen, wie der Mitentwickler per1234 ja schrieb.