mikrocontroller.net

Forum: PC-Programmierung Struktur mit Zeigern anlegen


Autor: StefL_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, will ne Struktur mit Zeigern in C initialisieren.
Kann mal jemand kurz drüber schauen ob da so richtig geht.
typedef struct{
  PNIO_UINT32 dwHandle;
  PNIO_UINT8 NumOfIODevives;
  PNIO_UINT8 MaxLen;
  volatile PNIO_MODE_TYPE currentMode;
  volatile PNIO_IOXS localState;
  
  volatile PNIO_IOXS* deviceInputState;

  PNIO_ADDR* deviceInputAddress;
  PNIO_UINT32* deviceInputLength;
  PNIO_UINT8** deviceInputData;

  volatile PNIO_IOXS* deviceOutputState;

  PNIO_ADDR* deviceOutputAddress;
  PNIO_UINT32* deviceOutputLength;
  PNIO_UINT8** deviceOutputData; 
}PNIO_init;
_declspec(dllexport)PNIO_init* setUpDevice(PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)//, PNIO_init* PNIO_init_struct)
{  
  PNIO_init PNIO_init_struct;
  PNIO_init_struct.NumOfIODevives = NumberOfDevices;
  PNIO_init_struct.MaxLen = MaxLen;
  PNIO_init_struct.currentMode = g_currentMode;
  PNIO_init_struct.localState = PNIO_S_GOOD;
  
  PNIO_init_struct.deviceInputState = (PNIO_IOXS*)malloc( NumberOfDevices * sizeof( PNIO_IOXS ) );
  PNIO_init_struct.deviceInputState[NumberOfDevices];
  PNIO_init_struct.deviceInputAddress = (PNIO_ADDR*)malloc( NumberOfDevices * sizeof( PNIO_ADDR ) );
  PNIO_init_struct.deviceInputAddress[NumberOfDevices];
  PNIO_init_struct.deviceInputLength = (PNIO_UINT32*)malloc( NumberOfDevices * sizeof( PNIO_UINT32 ) );
  PNIO_init_struct.deviceInputLength[NumberOfDevices];
  PNIO_init_struct.deviceInputData = (PNIO_UINT8**)malloc( NumberOfDevices * sizeof( PNIO_UINT8 ) * MaxLen * sizeof( PNIO_UINT8 ) );
  PNIO_init_struct.deviceInputData[NumberOfDevices][MaxLen];

  PNIO_init_struct.deviceOutputState = (PNIO_IOXS*)malloc( NumberOfDevices * sizeof( PNIO_IOXS ) );
  PNIO_init_struct.deviceOutputState[NumberOfDevices];
  PNIO_init_struct.deviceOutputAddress = (PNIO_ADDR*)malloc( NumberOfDevices * sizeof( PNIO_ADDR ) );
  PNIO_init_struct.deviceOutputAddress[NumberOfDevices];
  PNIO_init_struct.deviceOutputLength = (PNIO_UINT32*)malloc( NumberOfDevices * sizeof( PNIO_UINT32 ) );
  PNIO_init_struct.deviceOutputLength[NumberOfDevices];
  PNIO_init_struct.deviceOutputData = (PNIO_UINT8**)malloc( NumberOfDevices * sizeof( PNIO_UINT8 ) * MaxLen * sizeof( PNIO_UINT8 ) );
  PNIO_init_struct.deviceOutputData[NumberOfDevices][MaxLen];

.......................................
.......................................

  return &PNIO_init_struct;
}

Oder kann ich mir das Speicherresrvieren mit malloc auch sparen.

Kann man aus einer dll eine Adresse einer Variable an C# übergeben und 
vor allem, funktioniert das dann auch ;-)

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

Bewertung
0 lesenswert
nicht lesenswert
Du legst eine Instanz der Struktur als lokale Variable an, d.h. auf 
dem Stack, und gibst einen Pointer auf diese Variable zurück:

StefL_ schrieb:
> _declspec(dllexport)PNIO_init* setUpDevice(PNIO_UINT8 NumberOfDevices, 
PNIO_UINT8 MaxLen)//, PNIO_init* PNIO_init_struct)
> {
>   PNIO_init PNIO_init_struct;
>
>   return &PNIO_init_struct;
> }

Sobald aber die Funktion zurückkehrt, ist der von ihr auf dem Stack 
belegte Speicher freigegeben ...

Das geht in die Hose.

Autor: StefL_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, danke für die schnelle Antwort.
wie kann ich es dann machen?
_declspec(dllexport)PNIO_init* setUpDevice(PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)
{
  PNIO_init* PNIO_init_struct;
  PNIO_init_struct->NumOfIODevives = NumberOfDevices;
.
.
.
  return PNIO_init_struct;

oder
_declspec(dllexport)void setUpDevice(PNIO_init* PNIO_init_struct, PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)
{
  PNIO_init_struct->NumOfIODevives = NumberOfDevices;
.
.
.
muss bei dieser Variante die Größe der Struktur nicht beim Aufruf der 
Funktion schon bekannt sein!?
wie würdet ihr das machen?

Autor: Markus Volz (valvestino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es stellt sich mir die Frage, wieso Du in C Speicher allokierst und 
diesen dann in C# verwenden willst. So wie ich das Code-Stück oben 
überblicke passiert nichts weiter als Speicher zu allokieren (was, wie 
Rufus bereits geschireben hat, nicht korrekt umgesetzt ist).

Du kannst diesen Speicher so nicht direkt in C# verwenden. Du mußt mit 
Hilfe der Marshalling-Funktionen des .net-PInvoke entsprechende 
Datenstrukturen in C# füllen. Solange Du keine weitere Funktionalität in 
der C-Funktion hast, ist das reichlich sinnlos.

Gruß
Markus

Autor: StefL_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Funktion wird die Struktur noch mit Daten aufgefüllt. Ist nicht 
so sinnlos ;-).
Problem ist folgendes, ich habe weitere Funktionen in der C-dll die die 
gefüllte Struktur brauchen. Wollte das jetzt so machen:
in einer Funktion wird die Struktur gefüllt (siehe oben)
die Adresse der Struktur wird an C# geliefert
in C# werden weitere Funktionen der dll aufgerufen, denen übergebe ich 
dann jeweils wieder die Adresse der Struktur.
Wollte das in C# mit einem void Zeiger erledigen.

Ist das so möglich?
Bin eigentlich in der C-Welt zu Hause. Erste Versuche mit C# :-)...

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

Bewertung
0 lesenswert
nicht lesenswert
StefL_ schrieb:
> Ok, danke für die schnelle Antwort.
> wie kann ich es dann machen?
>
> _declspec(dllexport)PNIO_init* setUpDevice(PNIO_UINT8 NumberOfDevices,
> PNIO_UINT8 MaxLen)
> {
>   PNIO_init* PNIO_init_struct;
>   PNIO_init_struct->NumOfIODevives = NumberOfDevices;
> .
> .
> .
>   return PNIO_init_struct;
> 

So gar nicht, wo ist der Speicher, auf den der Pointer PNIO_init_struct 
zeigt?


> oder
>
>
> _declspec(dllexport)void setUpDevice(PNIO_init* PNIO_init_struct,
> PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)
> {
>   PNIO_init_struct->NumOfIODevives = NumberOfDevices;
> .
> .
> .
> 

Ja, genau so.

> muss bei dieser Variante die Größe der Struktur nicht beim Aufruf der
> Funktion schon bekannt sein!?

Das ist er doch.

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
StefL_ schrieb:
> In der Funktion wird die Struktur noch mit Daten aufgefüllt. Ist nicht
> so sinnlos ;-).
> Problem ist folgendes, ich habe weitere Funktionen in der C-dll die die
> gefüllte Struktur brauchen. Wollte das jetzt so machen:
> in einer Funktion wird die Struktur gefüllt (siehe oben)
> die Adresse der Struktur wird an C# geliefert
> in C# werden weitere Funktionen der dll aufgerufen, denen übergebe ich
> dann jeweils wieder die Adresse der Struktur.
> Wollte das in C# mit einem void Zeiger erledigen.
>
> Ist das so möglich?
> Bin eigentlich in der C-Welt zu Hause. Erste Versuche mit C# :-)...

PNIO klingt nach Profinet...dann gibt's das je nach Anwendungszweck auch 
fertig...

Ansonsten für den Anfang:
http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
http://msdn.microsoft.com/en-us/magazine/cc163910.aspx
http://msdn.microsoft.com/en-us/library/sd10k43k.aspx

Autor: StefL_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Hilfe...

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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