Struktur mit Zeigern anlegen

Gast #2013593
Hi, will ne Struktur mit Zeigern in C initialisieren.
Kann mal jemand kurz drüber schauen ob da so richtig geht.
1
typedef struct{
2
  PNIO_UINT32 dwHandle;
3
  PNIO_UINT8 NumOfIODevives;
4
  PNIO_UINT8 MaxLen;
5
  volatile PNIO_MODE_TYPE currentMode;
6
  volatile PNIO_IOXS localState;
7
  
8
  volatile PNIO_IOXS* deviceInputState;
9

10
  PNIO_ADDR* deviceInputAddress;
11
  PNIO_UINT32* deviceInputLength;
12
  PNIO_UINT8** deviceInputData;
13

14
  volatile PNIO_IOXS* deviceOutputState;
15

16
  PNIO_ADDR* deviceOutputAddress;
17
  PNIO_UINT32* deviceOutputLength;
18
  PNIO_UINT8** deviceOutputData; 
19
}PNIO_init;
1
_declspec(dllexport)PNIO_init* setUpDevice(PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)//, PNIO_init* PNIO_init_struct)
2
{  
3
  PNIO_init PNIO_init_struct;
4
  PNIO_init_struct.NumOfIODevives = NumberOfDevices;
5
  PNIO_init_struct.MaxLen = MaxLen;
6
  PNIO_init_struct.currentMode = g_currentMode;
7
  PNIO_init_struct.localState = PNIO_S_GOOD;
8
  
9
  PNIO_init_struct.deviceInputState = (PNIO_IOXS*)malloc( NumberOfDevices * sizeof( PNIO_IOXS ) );
10
  PNIO_init_struct.deviceInputState[NumberOfDevices];
11
  PNIO_init_struct.deviceInputAddress = (PNIO_ADDR*)malloc( NumberOfDevices * sizeof( PNIO_ADDR ) );
12
  PNIO_init_struct.deviceInputAddress[NumberOfDevices];
13
  PNIO_init_struct.deviceInputLength = (PNIO_UINT32*)malloc( NumberOfDevices * sizeof( PNIO_UINT32 ) );
14
  PNIO_init_struct.deviceInputLength[NumberOfDevices];
15
  PNIO_init_struct.deviceInputData = (PNIO_UINT8**)malloc( NumberOfDevices * sizeof( PNIO_UINT8 ) * MaxLen * sizeof( PNIO_UINT8 ) );
16
  PNIO_init_struct.deviceInputData[NumberOfDevices][MaxLen];
17

18
  PNIO_init_struct.deviceOutputState = (PNIO_IOXS*)malloc( NumberOfDevices * sizeof( PNIO_IOXS ) );
19
  PNIO_init_struct.deviceOutputState[NumberOfDevices];
20
  PNIO_init_struct.deviceOutputAddress = (PNIO_ADDR*)malloc( NumberOfDevices * sizeof( PNIO_ADDR ) );
21
  PNIO_init_struct.deviceOutputAddress[NumberOfDevices];
22
  PNIO_init_struct.deviceOutputLength = (PNIO_UINT32*)malloc( NumberOfDevices * sizeof( PNIO_UINT32 ) );
23
  PNIO_init_struct.deviceOutputLength[NumberOfDevices];
24
  PNIO_init_struct.deviceOutputData = (PNIO_UINT8**)malloc( NumberOfDevices * sizeof( PNIO_UINT8 ) * MaxLen * sizeof( PNIO_UINT8 ) );
25
  PNIO_init_struct.deviceOutputData[NumberOfDevices][MaxLen];
26

27
.......................................
28
.......................................
29

30
  return &PNIO_init_struct;
31
}

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 ;-)
Persönliche Seite
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.
Gast
Ok, danke für die schnelle Antwort.
wie kann ich es dann machen?
1
_declspec(dllexport)PNIO_init* setUpDevice(PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)
2
{
3
  PNIO_init* PNIO_init_struct;
4
  PNIO_init_struct->NumOfIODevives = NumberOfDevices;
5
.
6
.
7
.
8
  return PNIO_init_struct;

oder
1
_declspec(dllexport)void setUpDevice(PNIO_init* PNIO_init_struct, PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)
2
{
3
  PNIO_init_struct->NumOfIODevives = NumberOfDevices;
4
.
5
.
6
.
muss bei dieser Variante die Größe der Struktur nicht beim Aufruf der 
Funktion schon bekannt sein!?
wie würdet ihr das machen?
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
Gast
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# :-)...
Persönliche Seite
StefL_ schrieb:
> Ok, danke für die schnelle Antwort.
> wie kann ich es dann machen?
>
1
> _declspec(dllexport)PNIO_init* setUpDevice(PNIO_UINT8 NumberOfDevices,
2
> PNIO_UINT8 MaxLen)
3
> {
4
>   PNIO_init* PNIO_init_struct;
5
>   PNIO_init_struct->NumOfIODevives = NumberOfDevices;
6
> .
7
> .
8
> .
9
>   return PNIO_init_struct;
10
>

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


> oder
>
>
1
> _declspec(dllexport)void setUpDevice(PNIO_init* PNIO_init_struct,
2
> PNIO_UINT8 NumberOfDevices, PNIO_UINT8 MaxLen)
3
> {
4
>   PNIO_init_struct->NumOfIODevives = NumberOfDevices;
5
> .
6
> .
7
> .
8
>

Ja, genau so.

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

Das ist er doch.
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.