Laden...

Typumwandlung Struct C in C#: Zeigervariablen und Zeiger auf Funktionen

Erstellt von clamb vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.210 Views
C
clamb Themenstarter:in
5 Beiträge seit 2012
vor 10 Jahren
Typumwandlung Struct C in C#: Zeigervariablen und Zeiger auf Funktionen

Hallo,

ich beschäftige mich zur Zeit mit der Menüstruktur des AVR Butterfly und versuche diese von C in C# umzustricken. Da meine Erfahrungen in C# sehr gering sind, bin ich auch direkt auf ein Problem gestossen.

Zunächst einmal hier ein Ausschnitt des alten Codes:


#define ST_AVRBF                = 10;
#define ST_AVRBF_REV         = 11;
char MT_AVRBF[]                     = "AVR Butterfly";
.....

typedef struct
{
    unsigned char state;
    unsigned char input;
    unsigned char nextstate;
} MENU_NEXTSTATE;


typedef struct
{
    unsigned char state;
    char  *pText;
    char (*pFunc)(char input);
} MENU_STATE;

MENU_NEXTSTATE menu_nextstate[] = {
//   STATE                         INPUT          NEXT STATE
    {ST_AVRBF,                  KEY_PLUS,   ST_OPTIONS},
    {ST_AVRBF,                  KEY_NEXT,    ST_AVRBF_REV}
};

MENU_STATE menu_state[] = {
//  STATE                               STATE TEXT              STATE_FUNC
    {ST_AVRBF,                       MT_AVRBF,                NULL},
    {ST_AVRBF_REV,                NULL,                       Revision}
};

Und hier mein erster Versuch den Code in C# umzuschreiben.


public const int ST_AVRBF                = 10;
public const int ST_AVRBF_REV         = 11;
char[] MT_AVRBF                     = {'A','V','R',' ','B','u','t','t','e','r','f','l','y'};
....

public struct MENU_NEXTSTATE
        {
            int state;
            int input;
            int nextstate;

            public MENU_NEXTSTATE(int _state, int _input, int _nextstate)
            {
                state       = _state;
                input       = _input;
                nextstate   = _nextstate;
            }
        }


        unsafe public struct MENU_STATE
        {
            int state;
            char* pText;
            char *pFunc(char input);
        }

MENU_NEXTSTATE[] menu_nextstate = {
//                                   STATE                      INPUT                   NEXT STATE
   new MENU_NEXTSTATE(ST_AVRBF,                KEY_PLUS,            ST_OPTIONS),
   new MENU_NEXTSTATE(ST_AVRBF,                KEY_NEXT,            ST_AVRBF_REV)
};

MENU_STATE[] menu_state = {
                        // STATE                              STATE TEXT               STATE_FUNC
   new MENU_STATE(ST_AVRBF,                      MT_AVRBF,                NULL),
   new MENU_STATE(ST_AVRBF_REV,               NULL,                       Revision)
};

Mein Frage ist: Wie muss der Konstruktor des Structs MENU_STATE aussehen, wenn dieser Zeigervariablen und Zeiger auf Funktionen beinhaltet?
Und gibt es sonst noch Verbesserungsvorschläge?

Gruß
C

C
clamb Themenstarter:in
5 Beiträge seit 2012
vor 10 Jahren

Windows XP verweigert mir leider die Installation, da es sich angeblich um eine schädliche Software handelt. Gibt es alternativen?

64 Beiträge seit 2012
vor 10 Jahren

Gibt es alternativen?

Zu Windows XP - natürlich 😉

++Rekursion ++
(lat. , die) siehe Rekursion

4.931 Beiträge seit 2008
vor 10 Jahren

Dein C-Code ist aber fehlerhaft. Nach Korrektur zu


#define ST_AVRBF                10
#define ST_AVRBF_REV         11

hat der Interop Assistant folgenden C#-Code erzeugt:


public partial class NativeConstants
{   
    /// ST_AVRBF -> 10
    public const int ST_AVRBF = 10;
    
    /// ST_AVRBF_REV -> 11
    public const int ST_AVRBF_REV = 11;
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MENU_NEXTSTATE
{   
    /// unsigned char
    public byte state;
    
    /// unsigned char
    public byte input;
    
    /// unsigned char
    public byte nextstate;
}

/// Return Type: char
///input: char
public delegate byte _pFunc(byte input);

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MENU_STATE
{   
    /// unsigned char
    public byte state;
    
    /// char*  [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
    public string pText;
    
    /// _pFunc
    public _pFunc AnonymousMember1;
}

Bzgl. des Funktionszeigers im C-Code wurde daraus dann ein Delegat erzeugt (ansonsten stimmte aber dein Code weitesgehendst).

Die generelle Frage ist jetzt aber: willst du den C-Code einfach nur nach C# portieren oder möchtest du von C# aus auf eine C-Bibliothek zugreifen?

Ich würde dir auch raten, auf "unsafe" Code in C# zu verzichten.

C
clamb Themenstarter:in
5 Beiträge seit 2012
vor 10 Jahren

Ah ok, mit delegate.
Ich will diesen nach C# portieren, auf C Bibliotheken ist kein Zugriff notwendig.

Würde dann der vollständige Konstruktor für MENU_STATE so aussehen?


public delegate byte _pFunc(byte input);
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]

public struct MENU_STATE
{
    public byte state;
    public string pText;
    public _pFunc AnonymousMember1;

    public MENU_STATE(byte _state, string _pText, _pFunc _AnonymousMember1)
    {
          state = _state;
          pText = _pText;
          AnonymousMember1 = _AnonymousMember1;
     }
}

4.931 Beiträge seit 2008
vor 10 Jahren

Ja, sollte so funktionieren.

Du solltest dann aber statt "_AnonymousMember1" einen besseren Namen erzeugen (z.B. onInput) - k.A. warum das Tool diesen Membernamen erzeugt (anstatt den Namen "pFunc" zu übernehmen).

C
clamb Themenstarter:in
5 Beiträge seit 2012
vor 10 Jahren

Alles klar. Besten Dank. Es funktioniert.