adresse von Struktur aus anderer C-Datei bekommen

OP #7492687
Lesenswert?

Hallo, ich habe ein Problem, wo ich nicht weiterkomme und erhoffe mir hier um etwas hilfe.

Ich habe in src1.h eine Struktur deklariert. In src1.c wird diese definiert und damit gearbeitet. in src2.c habe ich src1.h inkludiert, damit ich die Struktur kenne. In src2.c habe ich einen Pointer der struktur erstellt. Ich möchte gerne, dass dieser auf die Struktur in src1.c zeigt, sodass wenn ich in src2.c daten darin ändere, diese in src1.c geändert sind.

src1.h

1
typedef struct
2
{
3
  uint8 x;
4
} Name_ts;

src1.c

1
Name_ts name_s;
2

3
...
4
void getStructAddress(Name_ts** name_pps)
5
{
6
  if (NULL != name_pps)
7
  {
8
    name_pps = &name_s;
9
  }
10
}

src2.c

1
#include "src1.h"
2
...
3

4
Name_ts* name_ps;
5
...
6
...
7

8
getStructAddress(name_ps)

aber nach aufruf der Funktion getStructAddress ist die adresse von name_ps immer noch 0.

OP #7492701
Lesenswert?

Wilhelm M. schrieb:

Bist Du sicher, dass das ohne Warnungen kompiliert? Du hast einen Typ-Mismatch. Schau dir nochmal das Argument an, was Du der Funktion übergibst.

Ja, da hast du recht gehabt.

src2.c

1
Name_ts* name_ps;
2
...
3
getStructAddress(&name_ps)

src1.c

1
void getStructAddress(Name_ts** name_pps)
2
{
3
  if (NULL != name_pps)
4
  {
5
    *name_pps = &name_s;
6
  }
7
}
#7492707
Lesenswert?

Und Warnungen gab es kein? Wohl kaum ...

Das ganze sieht ja auch mehr nach Übungsaufgabe aus. Deswegen will ich auch einmal grundsätzlich die Frage stellen, was die Semantik der Funktion getStructAddress() sein soll.

Gehört NULL tatsächlich zum zugelassenen Wertebereich des Paraameters name_pps? Falls ja, dann ist alles ok. Falls nein, d.h. es ist ein Fehler des Programmierers, jemals diese Funktion mit NULL aufzurufen, dann ist das if-statement falsch, und es gehört dort eine Zusicherung hin.

Besprich das mal mit Deinem Lehrer ...

#7492758
Lesenswert?

Das wäre meine implementierung, wenn man mit den Pointern so arbeiten will ;)

src1.h

1
typedef struct
2
{
3
  uint8 x;
4
} Name_ts;
5

6
extern void getStructAddress(Name_ts* name_pps);

src1.c

1
#include "src1.h"
2

3
static Name_ts name_s;
4

5
void getStructAddress(Name_ts* name_pps)
6
{
7
  // mal weggelassen, da wenn der Zeiger nicht initialisiert ist irgendwas drinsteht.
8
  //if (NULL != name_pps)
9
  //{
10
    name_pps = &name_s;
11
  //}
12
}

src2.c

1
#include "src1.h"
2

3
Name_ts* name_ps;
4
getStructAddress(name_ps);

Wo man sich jetzt noch streiten könnte, ob man die Adresse als return wert zurückgibt oder über einen Parameter ist die Frage. Kann man machen wie man will... Das meiste optimiert sowiso der Compiler weg. Bei guter Optimierung wird die Funktion sowiso direkt durch die Adresse ersetzt.

#7492824
Lesenswert?

Yalu X. schrieb:

Joh S. schrieb:

Das wäre meine implementierung, wenn man mit den Pointern so arbeiten will ;) ...

Das ist doch fast der gleiche Code wie der des TE, nur dass du zu den zwei Fehlern des Originals noch einen dritten hinzugefügt hast.

Wo sollen da 3 Fehler drin sein? Compiliert einwandfrei. Ja es ist fast der gleiche Code. Die Frage war ja, was man ändern muss, damit der Code funktioniert.

Ob man jetzt einen Pointer übergibt oder als return Wert liefert ist meiner Meinung nach total egal. Im AutoSAR kontext ist sowas normal, da immer ein Std_ReturnType mit E_OK oder E_NOT_OK zurückgeliefert wird ...

#7492827
Lesenswert?

Der TO wollte es wahrscheinlich in etwa so machen : (es hat nix mit der Aufteilung auf mehrere Dateien zu tun)

1
#include <stdio.h>
2
#include <stdint.h>
3

4
typedef struct{
5
  uint8_t x;
6
} Name_ts;
7

8
Name_ts name_s;
9
Name_ts* name_ps;
10

11
void getStructAddress(Name_ts** name_pps) {
12
  if (NULL != name_pps) {
13
    *name_pps = &name_s;
14
  }
15
}
16

17
int main() {
18
  printf("Hello, World!\n");
19
  printf("%8p\n",&name_s);
20
  getStructAddress(&name_ps);
21
  printf("%8p\n",name_ps);
22
  return 0;
23
}

Es fehlen ein paar entscheidende '*' bzw. '&'.

Moderator #7492834
Lesenswert?

Joh S. schrieb:

Wo sollen da 3 Fehler drin sein? Compiliert einwandfrei.

Ja, die Warnungen sind weg (wenn man die fehlende Deklaration von uint8 noch hinzufügt).

Ja es ist fast der gleiche Code. Die Frage war ja, was man ändern muss, damit der Code funktioniert.

Keine Warnungen und funktionieren sind zweierlei Dinge. Hast du deinen Code mal getestet?

#7492852
Lesenswert?

Yalu X. schrieb:

Joh S. schrieb:

Wo sollen da 3 Fehler drin sein? Compiliert einwandfrei.

Ja, die Warnungen sind weg (wenn man die fehlende Deklaration von uint8 noch hinzufügt).

Ja es ist fast der gleiche Code. Die Frage war ja, was man ändern muss, damit der Code funktioniert.

Keine Warnungen und funktionieren sind zweierlei Dinge. Hast du deinen Code mal getestet?

da war es anscheinend noch zu früh... Ist natürlich dumm, wenn man eine kopie des zeigers übergibt...

Somit schließe ich mich der allgemeinen meinung an, dass der Zeiger auf die Instanz als return-Wert am sinnvollsten wäre.

Angehängte Dateien:
#7492861
Lesenswert?

Joh S. schrieb:

Somit schließe ich mich der allgemeinen meinung an, dass der Zeiger auf die Instanz als return-Wert am sinnvollsten wäre.

Der TO hat ja nur einen Testcode geliefert. Was also wenn die Funktion so aus sieht :

1
uint8_t getStructAddress(Name_ts** name_pps) {
2
  if (NULL != name_pps) {
3
    *name_pps = &name_s;
4
    return 0;
5
  }
6
  return -1;
7
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren