mikrocontroller.net

Forum: PC-Programmierung Adresse vom Struct global speichern um später drauf zu schreiben


Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe eine Funktion der ein Struct als Pointer übergeben wird
void start (Message * const TxMessage)
und eine Funktion die jede 10 ms (aus einer anderen Funktion) aufgerufen 
wird
void writeInterface(void)
(Das aber nur, wenn start vorher aufgerufen wurde).
Jetzt möchte ich in der writeInterface-Funktion TxMessage beschreiben.
Dazu würde ich die Adresse vom Pointer in der Funktion start auf eine 
Globale variable speichern.

Hieran scheitere ich allerdings gerade. Ist meine Idee so überhaupt 
möglich?

Hat jemand einen Tip, was/wie ich es genau machen muss?

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahso, was ich bisher versucht habe ist eine globale variable zu 
erstellen
static Message TxMessageGlobal

und in der Funktion Start+
 TxMessage = &TxMessageGlobal;
TxMessageGlobal würde ich dann in der Funktion writeInterface benutzen.
 TxMessageGlobal.size = 0x01;
 TxMessageGlobal.value[0]= 0x7F;
 Allerdings stürtzt das Programm immer beim beschreiben immer ab

Autor: foobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  TxMessageGlobal.size = 0x01;
>  TxMessageGlobal.value[0]= 0x7F;
>
> Allerdings stürtzt das Programm immer beim beschreiben immer ab

Ist .value evtl ein (nicht initialisierter) Pointer?

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jan schrieb:
> Dazu würde ich die Adresse vom Pointer in der Funktion start auf eine
> Globale variable speichern.

Kann man so machen. Aber das machst Du nicht :

> static Message TxMessageGlobal

Das ist kein Pointer, und das ist keine globale Variable, sondern nur 
eine innerhalb des Moduls/der "translation unit" sichtbare Variable.

> TxMessage = &TxMessageGlobal;

Das setzt den der Funktion übergebenen Wert auf die Adresse der globalen 
Variablen.

Du willst zwei andere Dinge erreichen:

a) Deine "globale" Variable soll ein Pointer werden

b) Du willst in start diesem Pointer den der Funktion übergebenen 
Pointer zuweisen.

Message *TxMessageGlobal;

void start (Message * const TxMessage)
{
  TxMessageGlobal = TxMessage;

  // ... 
}

void writeInterface(void)
{
  if (TxMessageGlobal)
  {
    TxMessageGlobal->size = 0x01;
    TxMessageGlobal->value[0]= 0x7F;
  }
}

Das "if (TxMessageGlobal)" prüft, ob dem Pointer bereits ein Wert 
zugewiesen wurde.

Dieser Pointer ist ohne den Aufruf von "start" per Default mit NULL 
initialisiert, und das kann auf diese Art und Weise erkannt werden.



Voraussetzung dafür, daß das ganze was sinnvolles macht, ist, daß der 
der Funktion start übergebene Pointer auf einen dauerhaft mit Inhalt 
versehenen Speicherbereich zeigt (und nicht nur auf eine in der 
Aufruferfunktion lokale Variable).

: Bearbeitet durch Moderator
Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:
> Kann man so machen. Aber das machst Du nicht :

Ja, das ganze mit den Pointern tu ich mich noch ein bisschen schwer mit.

Aber so wie du es vorgemacht hast, funktioniert es. Meine Idee an sich 
hat also funktioniert, nur bei der Umsetzung bin ich gescheitert.

Du hast geschrieben "Kann man so machen.". Was gäbe es denn anderes als 
Alternative?

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jan schrieb:
> Was gäbe es denn anderes als Alternative?

Kann man, ohne den Kontext zu kennen, schwer beantworten.

Woher kommt der der Funktion start übergebene Pointer?

Autor: foobar (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Ich schrieb:
> Ist .value evtl ein (nicht initialisierter) Pointer?

Man sollte nicht vorm ersten Kaffee antworten, die Antwort gehört wohl 
zur "Not even wrong" Klasse - nicht falsch, aber irrelevant.

Zum Ausgleich etwas, warum dein Ansatz verkehrt sein dürfte/könnte:

Man muß bei solchen Sachen im Auge haben, wem das Objekt gehört und 
entsprechend, wer damit hantieren darf.

Üblich bei solchen Funktionen wie deinem "start" ist, dass das Objekt 
(die TxMessage) dem Aufrufer gehört und er es dieser Funktion für eine 
Weile überlässt.  Was die Funktion währenddessen damit machen darf, 
steht irgendwo in der Systembeschreibung (z.B. lesen ok, ändern 
verboten).  Sobald die Funktion zurückkehrt, ist wieder der Aufrufer der 
Verantwortliche - er kann das Objekt jetzt für andere Aktionen 
verwenden, es wieder freigeben oder sonstwas mit machen.

In einigen Fällen wird das Objekt der Funktion auf Dauer übergeben 
(Besitzerwechsel).  Der Aufrufer wird es nicht mehr anfassen, auch wenn 
die Funktion zurückgekehrt ist.  Sie hat sich jetzt darum zu kümmern, 
dass das Objekt irgendwann wieder freigegeben wird, etc - sie bestimmt 
die Lebensdauer.

Welcher Fall vorliegt, kann man so nicht sagen, das hängt von deinem 
konkreten Programm/System ab - das meinte Rufus mit "ohne Kontext schwer 
zu sagen".

Im ersten Fall wäre deine Methode verkehrt: sie würde das Objekt ändern, 
das ihr gar nicht mehr gehört - evtl nicht mal mehr existiert (sprich, 
du schreibst wild im Speicher herum).

Im zweiten Fall müßtest du dich darum kümmern, dass das Objekt auch 
irgendwann wieder freigegeben wird, sonst läuft irgendwann dein Speicher 
über.

Wenn man in einer solchen Bredouille steckt, ist das oft ein Zeichen, 
dass man die API falsch benutzt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.