Laden...

Wie kann ich einen Paramter vom Typ "ref byte[]" richtig übergeben?

Erstellt von chh2807 vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.640 Views
C
chh2807 Themenstarter:in
33 Beiträge seit 2015
vor 4 Jahren
Wie kann ich einen Paramter vom Typ "ref byte[]" richtig übergeben?

Hallo,

für meinen Job muss ich ein kleines Programm schreiben zur Fehlerauslese einer bestimmten Hardware. Da bin ich dann gezwungen externe Treiber bzw. .dlls zu verwenden.

Alles funktioniert auch so weit, im Debugger kann ich mir die Antworten der Prüflings anschauen. Es ist alles korrekt. Ich kann die Daten nur nicht weiter verarbeiten 🤔

Ein Aufruf sieht zum Beispiel so aus:

Local_Obj.Write(ClassID, Instance, Attribute, Service, DataOut, 6, ref Resp, ref RespLength);

Hier das Gegenstück aus der .dll:

public void Write(int Class, int Instance, int Attribute, int serviceCode, byte[] writeData, int writeDataLength, ref byte[] respBuffer, ref int respLength)

Es geht um das vorletzte Byte, den Responsebuffer. Bisher hab ich sämtliche mir bekannten Funktionen zu Typkonvertierung versucht aber bekommen immer sowas wie " cs0029 cannot implicitly convert type 'string[]' to 'string'" oder ähnliches.

Wie bekomm ich nun aus solchen "ref bytes" eine brauchbare Variable die ich ausgeben weiter verarbeiten kann?

Vielen Dank.
Mfg Chh

MFG
Chh

T
2.219 Beiträge seit 2008
vor 4 Jahren

Was du brauchst ist vermutlich die BitConverter Klasse von .NET um die Bytes in den richtigen Datentypen zu wandeln.

Doku

Nachtrag:
Deine Beispielfehlermeldung deutet aber auf eine andere Stelle an, als du hier zeigst.
Die Konvertierung in der Meldung deutet nämlich darauf hin, dass du bereits die Bytes in ein String Array umgewandelt hast und nun das Array in einen String konvertieren willst, was nicht funktionieren kann.

Hier müsstest du vielleicht den restlichen Code sowie einen Hinweis was dein Ziel sein soll posten.
Dann kann man auch prüfen ob du auf dem richtigen Weg bist.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

C
chh2807 Themenstarter:in
33 Beiträge seit 2015
vor 4 Jahren

Das stimmt. Der Code sieht nur so aus, nach dem resize gehts zurück ins Hauptprogramm:


int RespLength = 4;
int ClassID = 0x01;
int Instance = 1;
int Attribute = 1;
int Service = 0x01;
byte[] DataOut = new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };            
                        
Resp = new byte[256];

Local_Obj.Write(ClassID, Instance, Attribute, Service, DataOut, 6, ref Resp, ref RespLength);
Array.Resize(ref Resp, RespLength);

Die Datenübergabe zurück klappt, nur die Umwandlung im Hauptprogramm nicht mehr. Im Hauptprogramm möchte ich nun das was in "Resp" steht ausgeben. Das sind entweder nur "0000" oder "FFFF". Mehr kommt da nicht.

MFG
Chh

16.807 Beiträge seit 2008
vor 4 Jahren

Sicherheitshalber gefragt: zeigt die Methodensignatur die echte Methode oder ist das hier ein PInvoke?

C
chh2807 Themenstarter:in
33 Beiträge seit 2015
vor 4 Jahren

Die Frage kann ich leider nicht beantworten. Ich habe meinen Aufruf und das Gegenstück aus der .dll (Variablennamen und Values abgeändert wegen Datenschutz) so wie es mir vorliegt rüber kopiert.

Edith: das müsste die echte Methode sein (wenn ich Pinvoke) richtig verstanden habe.

MFG
Chh

16.807 Beiträge seit 2008
vor 4 Jahren

Ist das eine .NET DLL, die Du konsumierst?

C
chh2807 Themenstarter:in
33 Beiträge seit 2015
vor 4 Jahren

Ja, das ist es.

MFG
Chh

16.807 Beiträge seit 2008
vor 4 Jahren

Okay, dann kann eigentlich der Fehler nicht von dieser Zeile kommen.

Der Fehler sagt, dass ein string-Array nicht in einen string umgewandelt werden kann.
In der Signatur ist kein string-Array zu sehen.

Resp ist ein Byte-Array und kann daher diese Fehlermeldung nicht auslösen.
Du zeigst jedoch die Initialisierung von Resp nicht; nur

Resp = new byte[256];

steht noch irgendwo string[] Resp?

Wäre toll, wenn Du vollständige Codeabschnitte zeigen würdest und nicht zu viel verfälschst.

C
chh2807 Themenstarter:in
33 Beiträge seit 2015
vor 4 Jahren

So sieht die KOmplette Funktion aus die ich aus dem Hauptprogramm aufrufe. So gibts zumindest keine Fehlermeldungen und ich bekomme die gewünschten Daten bis ins Hauptprogramm.

public FuncStatus pushbuttons(bool EnableInterface, out byte[] Resp)
        {
            int RespLength = 4;
            FuncStatus LocFct_Status = new FuncStatus();

            int ClassID = 0x01;
            int Instance = 1;
            int Attribute = 1;
            int Service = 0x01;
            byte[] DataOut = new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };            
                        
            Resp = new byte[256];

            try
            {
                if (!ConnectionOpen)
                    throw new Driver_Exception("There is no connection with the Device.");
                Local_Obj.Write(ClassID, Instance, Attribute, Service, DataOut, 6, ref Resp, ref RespLength);
                Array.Resize(ref Resp, RespLength);                
            }

            catch (Exception ex)
            {
                LocFct_Status.ErrorCode = -911;
                LocFct_Status.Message = "Command_Write Error" + ex.Message;
                return LocFct_Status;
            }
            return LocFct_Status;

        }

Im Hauptprogramm siehts folgendermaßen aus:

private void test_function_Click(object sender, EventArgs e)
        {
            bool DataOut = true;
            byte[] Response = new byte[256];
                        
            Device_Status = Commands.pushbuttons(DataOut, out Response);
            // Für den Teil Definitionen zu Beginn des Hauptprogramms 
            //Device_Calls  Commands = new Device_Calls();
            //Basics.FuncStatus Device_Status = new Basics.FuncStatus();

            rtb1.Text = "Button Status" + Response;          
                 
        }

Und bisher hab ich keinen Weg gefunden, im Hauptprogramm oder im Unterprogramm die Daten aus "Response" so zu konvertieren das ich sie in irgendeiner Form auf der Textbox ausgeben oder verarbeiten kann.

MFG
Chh

4.931 Beiträge seit 2008
vor 4 Jahren

Was genau steht denn in dem Byte-Array drin? Wenn es ein lesbarer Text (String) ist, warum gibt die Methode denn nicht den als String zurück? Oder ist die DLL von einem Fremdanbieter?

Wenn du weißt, um welches Text-Encoding es sich dabei handelt, dann kannst du eine der Encoding.GetString-Methoden benutzen:


string s = Encoding.Default.GetString(Response); // alternativ z.B. ASCII oder UTF8

PS: Die Zuweisung = new byte[256] vor dem Aufruf ist bei einem out-Parameter überflüssig (da sie ja von der Methode neu zugewiesen wird)!

T
2.219 Beiträge seit 2008
vor 4 Jahren

Für die Typenumwandlung musst du doch nur noch die BitConvert Klasse mit der entsprechenden Methode nehmen um dein byte Array in den entsprechenden Typen umzuwandeln.
Den Wert dann anzuzeigen kannst du dann auch einfach mit .ToString des jeweiligen Typen.

Beispiel (ungetestet) 😉


    Device_Status = Commands.pushbuttons(DataOut, out byte[] Response);

    // Beispiel zur Umwandlung des Array in einen Int
    int integer = BitConverter.ToInt32(Response)
    rtb1.Text = "Button Status" + integer;

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

C
chh2807 Themenstarter:in
33 Beiträge seit 2015
vor 4 Jahren

@T-Virus

Vielen Dank! Das mit dem Bitconverter hat mein Problem gelöst. Anstatt Integer hab ich zwar String gennommen / nehmen müssen aber das reicht ja. Dann mit der Funktion Status.Contains(x) auf den empfangenen Inhalt verglichen und schon hab ich meine gewünschte If-Abfrage.

@TH69
Die .dll ist von einem Fremdanbieter, deswegen war bzw bin ich in der Hinsicht eingeschränkt und muss irgendwie verwenden was mir angeboten wird.

MFG
Chh