DLL dezimal zu ascii

Anfängerfragen zum Programmieren mit PureBasic.
twofel
Beiträge: 18
Registriert: 20.03.2013 13:34

DLL dezimal zu ascii

Beitrag von twofel »

Hallo,

brauche mal eure Hilfe. Eine Meßtechnik-Software benötigt eine DLL um gewisse Aktionen auszuführen.

Einige Prozeduren zur Übergabe der PArameter sind vorgegeben.

So z.B. diese hier: ( hier wird Wert an in1 nur an out1 übergeben)

Code: Alles auswählen

; check inputs and set outputs while running...

ProcedureDLL CCalculate(*PInput.sDLLParams, *POutput.sDLLParams, *PUser.sDLLParams)

  Protected in1.d, out1.d

  in1 = *PInput\DLLParam[0]
    
  out1 = in1
    
  *POutput\DLLParam[0] = out1
 

EndProcedure
in1 ist der Eingang eines Bauteils...hier lese ich den Inhalt eines 16 bit Registers ein.

An out1 ( der entsprechende Ausgang) soll aber der ASCII Wert von in1 erscheinen.

Also sind das 2 ASCII Strings. Allerdings muessen die auch noch in der richtigen Reihefolge erscheinen.
D.h. das LSB des Registerinhaltes muss als zweites Zeichen und das MSB als erstes Zeichen an "out2" erscheinen.


z.b. Inhalt Register = 20051 (dec) entspricht hex = 4E 53 also ASCII = N S und vertauscht dann ASCII = SN
Dieser ASCII Wert muss dann an "out2" stehen.

Da ich noch nicht so fit in PUREBASIC bin, ich aber diese DLL unbedingt in dieser Sprache programmieren möchte,
wäre ich fuer eure Hilfestellung dankbar.


Gruss

Tim
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: DLL dezimal zu ascii

Beitrag von NicTheQuick »

Also einfach nur die zwei Bytes verdrehen?

Code: Alles auswählen

; check inputs and set outputs while running...

ProcedureDLL CCalculate(*PInput.sDLLParams, *POutput.sDLLParams, *PUser.sDLLParams)
	
	Protected in1.u, out1.u ;unsigned 16-Bit Werte anstatt Doubles!
	
	in1 = *PInput\DLLParam[0]
	
	out1 = ((in1 & $ff) << 8) | (in1 >> 8)
	
	*POutput\DLLParam[0] = out1
	
	
EndProcedure
//Edit: Danke, ts-soft.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: DLL dezimal zu ascii

Beitrag von ts-soft »

Funktioniert das denn mit den Doubles?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: DLL dezimal zu ascii

Beitrag von NicTheQuick »

Wohl eher nicht. Ist mir aber auch nicht aufgefallen. Hab das ganze nicht getestet. Jetzt ist es korrigiert.
twofel
Beiträge: 18
Registriert: 20.03.2013 13:34

Re: DLL dezimal zu ascii

Beitrag von twofel »

danke @ NicTheQuick und ts-soft.

Habs mal kurz getetstet....also die Bytes sind gedreht....funktioniert soweit.

Danke !!

Wie kriege ich jetzt den entspechenden ASCII -Wert der beiden bytes an den Ausgang "out1" ?

Muss ich eine neue Stringvariable noch hinzufügen ?



//Edit
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: DLL dezimal zu ascii

Beitrag von NicTheQuick »

Ob da jetzt ein B oder 66 steht, macht doch keinen Unterschied. Ein B ist ja auch nur eine bestimmte Zahl nach dem ASCII-Code eben.

Also nach deiner Beschreibung musst du doch nicht mehr machen als die Bytes zu drehen, oder?

Also ich verstehe nicht, was du mit ASCII Wert meinst. out1 ist ja ein 16-Bit-Wert, kann aber auch als String mit zwei Zeichen interpretiert werden. Aber jeder Buchstabe in diesem String ist ja auch nichts anderes als eine Zahl. Das heißt wenn ich die beiden 8-Bit-Zahlen tausche, sind ja automatisch auch die Buchstaben vertauscht. Dann redest du noch von einem "out2", was ich aber nirgendwo sehe.

Weiterhin hab ich keine Ahnung, was sDLLParams für eine Struktur ist, kann also ab jetzt nur noch raten.
twofel
Beiträge: 18
Registriert: 20.03.2013 13:34

Re: DLL dezimal zu ascii

Beitrag von twofel »

Hallo NicTheQuick,

ja du hast Recht. Letztlich muss man nur den Digitalwert interpretieren, um die
entsprechenden ASCII Zeichen zu erhalten.

Was die Struktur betrifft, die sieht so aus.

Code: Alles auswählen

Structure sDLLParams
  DLLParam.d[100]
EndStructure
Ich glaube, ich habe auch die falsche Prozedur erwischt. Jedenfalls habe ich gesehen, dass der Hersteller der Meßtechniksoftware
auch eine andere Prozedur zur Verarbeitung von Zeichenketten zur Verfügung stellt. Die müsste halt in PureBasic umgeschrieben werden.

hier die Herstellervorgaben:

Delphi: Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);
C++: void _stdcall CCalculateEx(double *PInput, double *POutput, double *PUser; StringParam PStrings)
Diese Methode wurde eingeführt um zusätzlich die Verarbeitung von Zeichenketten durch eine DLL zu ermöglichen und kann bei Bedarf alternativ
zu CALCULATE verwendet werden. Die Zeichenketten werden mit dem Parameter PSTRINGS übergeben. Dabei handelt es sich um eine Zeigervariable, deren Delphi-Deklaration so aussieht:

type TStringParams = array[0..100] of PChar;
PStringParams = ^TStringParams;
twofel
Beiträge: 18
Registriert: 20.03.2013 13:34

Re: DLL dezimal zu ascii

Beitrag von twofel »

Hallo,

soo..nachdem ich die richtige Prozedur fand, habe ich folgenden Code unter Nutzung der Hilfestellung von NicTheQuick
geschrieben.

Code: Alles auswählen

ProcedureDLL CCalculateEx(*PInput.sDLLParams, *POutput.sDLLParams, *PUser.sDLLParams,*PStrings.sStringParams)
   
   Protected  in1.u;unsigned 16-Bit Werte anstatt Doubles!
   Protected  ausgang1.s, out1.s,i.i
   
   ; in1 erhält Inhalt eines 16 bit Registers
   in1 = *PInput\DLLParam[0]
   
   ; Vertauschen der Bytereihenfolge (Endianness)  und Umwandlung in 2 HEX-Ausdrücke
   ausgang1.s = Hex(((in1 & $ff) << 8) | (in1 >> 8))
   
 
   ;Umwandlung von Hex in 2 ASCII Zeichen
   For i = 1 To (Len(ausgang1)/2)+1 Step 2 
  
    out1.s = out1 + Chr(Val("$"+Mid(ausgang1, i, 2))) 
  Next i 
    
  ;Übergabe des ASCII Strings
   *PStrings\StringParam[0] = out1   
   
   
 EndProcedure 
 
Ziel sollte ja sein den übergebenen Wert eines 16bit Registers in einen ASCII-String umzuwandeln und diesen dann
wieder an einen "Ausgangsparameter" der DLL zu übergeben.

Könnt ihr mal bitte drübergucken, ob es programmiertechnisch so ok ist .
Für Verbesserungshinweise wäre ich dankbar.

PS:
Die DLL, in der diese Prozedur vorkommt konnte ich in der Meßtechniksoftware mit erfolg testen.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: DLL dezimal zu ascii

Beitrag von NicTheQuick »

Mir stellt sich immer noch die Frage, warum die DLLParams-Structure Doubles enthält. Soll da wirklich mit Doubles gearbeitet werden?

Ansonsten scheint deine Methode zu funktionieren, aber einfacher wäre diese hier:

Code: Alles auswählen

in1.i = ...

in1Inverse = ((in1 & $ff) << 8) | (in1 >> 8)

ausgabe1.s = PeekS(@in1, 2)
out1.s = PeekS(@in1Inverse, 2)

Debug in1
Debug in1Inverse

Debug ausgabe1
Debug out1
twofel
Beiträge: 18
Registriert: 20.03.2013 13:34

Re: DLL dezimal zu ascii

Beitrag von twofel »

@NicTheQuick

Man oh man....das ist aber extrem kurz. Für meine Zwecke muesste
dann folgender Code reichen. PeekS...ist aber ein schöner Befehl :mrgreen:

Code: Alles auswählen

in1.i = < dec-zahl>

out1.s = PeekS(@in1, 2)

Die DLLParams-Structur ist in Doubles von der Messtechniksoftware vorgegeben...da kann ich nichts ändern.

Es heisst dort:

Alle drei Pointer PINPUT, POUTPUT und PUSER zeigen jeweils auf einen Speicherbereich in dem 100 Variablen vom Typ
EXTENDED in einem Array abgelegt sind. Die Pointer sind vom Typ PDLLParams, dessen Deklaration in Delphi so aussieht:

type TDLLParams = array[0..100] of extended;
PDLLParams = ^TDLLParams;

In C++ wird dieser Speicherbereich z.B. als (double *PInput) übergeben. ................................
Antworten