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
Was du brauchst ist vermutlich die BitConverter Klasse von .NET um die Bytes in den richtigen Datentypen zu wandeln.
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.
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
Sicherheitshalber gefragt: zeigt die Methodensignatur die echte Methode oder ist das hier ein PInvoke?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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
Ist das eine .NET DLL, die Du konsumierst?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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
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)!
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.
@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