Struktur mit Zeigern anlegen

Gast #2013593
Lesenswert?

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 #2013612
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.
Gast #2013619
Lesenswert?

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?
#2013652
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
Gast #2013667
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# :-)...
Persönliche Seite #2013915
Lesenswert?

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.
#2013930
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

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