Autor |
Beitrag |
chrissi68
Hält's aus hier
Beiträge: 4
|
Verfasst: Do 27.10.11 18:58
Hallo,
unter Delphi2007 hatte ich ein Programm zur Kommunikation mit RFID-Antennen geschrieben. Die externe Dll besitzt folgenden Funktionsaufruf:
Delphi-Quelltext 1:
| function FECOM_SetPortPara(iPortHnd: Integer; cPara: PChar; cValue: PChar): Integer; stdcall; external 'Fecom.DLL'; |
Aufgerufen habe ich die Funktion mit:
Delphi-Quelltext 1: 2: 3: 4: 5:
| var rBaudRate: PAnsiChar; . . cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'Baud', rBaudRate); |
Mittlerweile benutze ich Delphi XE und das Programm funzt nicht mehr  weil PChar jetzt Unicode-fähig ist. Anscheinend soll PChar mit PWideChar ersetzt werden. Dies
habe ich auch gemacht.....
Delphi-Quelltext 1:
| function FECOM_SetPortPara(iPortHnd: Integer; cPara: PWideChar; cValue: PWideChar): Integer; stdcall; external 'Fecom.DLL'; |
und die Variable "var rBaudRate: PWideChar" entsprechend geändert.
Leider klappt auch das nicht  .
Ersetze ich aber PWideChar durch PAnsiChar........
Delphi-Quelltext 1: 2: 3: 4:
| function FECOM_SetPortPara(iPortHnd: Integer; cPara: PAnsiChar; cValue: PAnsiChar): Integer; stdcall; external 'Fecom.DLL'; . . cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'Baud', '38400'); |
.... und rufe die Function mit dem statischen Wert auf, so klappt die Übergabe an die DLL!!
Vielleicht hat von Euch jemand eine Idee wie man die Parameterübergabe in Delphi XE hin bekommt, wäre klasse!
Viele Grüße
Chrissi
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 27.10.11 19:28
der einzige Fehler dürfte sein dass Du rBaudRate: PAnsiChar; auf eine String nicht auf einen AnsiString zeigen lässt.
Wenn Du für Para und Value AnsiStrings nimmst und diese über para[1] oder PAnsiChar(para) übergibst sollte es durchlaufen.
Vielleicht kannst Du an dem Beispiel sehen was ich meine
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Procedure ShowIt(p:PAnsiChar); begin Showmessage(p); end;
procedure TForm1.Button1Click(Sender: TObject); var s:String; s2:AnsiString; begin s := 'Test'; s2 := 'Test'; ShowIt(PAnsichar(s)); ShowIt(PAnsichar(s2)); end; |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Do 27.10.11 19:49
Wenn die DLL AnsiChars haben will, dann sollte man ihr auch welche geben, weil eventuell kommt sie mit WideChars nicht zu recht.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 27.10.11 20:11
Fecom.DLL und Ferwa.DLL sind definitiv steinnalt
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
jaenicke
      
Beiträge: 19326
Erhaltene Danke: 1749
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 28.10.11 06:19
chrissi68 hat folgendes geschrieben : | Anscheinend soll PChar mit PWideChar ersetzt werden. Dies
habe ich auch gemacht..... |
Um das einmal klarzustellen:
Nein, das ist falsch. Bis Delphi 2007 entsprach PChar = PAnsiChar. Seit Delphi 2009 entspricht PChar = PWideChar.
PChar in einer Schnittstellendefinition für eine DLL zu benutzen, war aber schon immer ein Programmierfehler, da es nicht dem konkreten Typ entspricht. Das gilt genauso für andere Metatypen wie Integer, Boolean usw., die dort auch nichts zu suchen haben. Stattdessen sollte immer ein konkreter Typ wie DWord, WordBool, ... benutzt werden um exakt zu definieren welche Größe die Datentypen haben.
Dies wurde auch schon viele Jahre vor der Umstellung auf Unicode gesagt, aber viele haben nicht darauf gehört.
(Wie auch auf die Warnungen vor dem Schreiben ins Exe-Verzeichnis z.B., beides mussten diejenigen mit der UAC in Vista bzw. Unicode in Delphi dann eben auf die harte Tour lernen.)
Wenn du jedenfalls in einer alten Schnittstelle PChar findest, ist dort immer PAnsiChar gemeint. An der Stelle musst du dann aber nach dem Ersetzen auch die Warnungen beachten, denn bei einem Cast von string (= UnicodeString ab Delphi 2009) auf PAnsiChar sollte eine Warnung vor einer bedenklichen Typumwandlung kommen.
|
|
chrissi68 
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 28.10.11 10:41
IHR SEID GROSSARTIG!!!!!!!!!!!!!
Vielen herzlichen Dank, jetzt funzt meine Function wieder!
Habe die PChar durch PAnsiChar ersetzt und übergebe jetzt AnsiString. Die Rückgabe erfolgt jetzt durch ein Array of AnsiChar, früher Array of Char
Hier der vollständige Code:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| function TFTestRFID.OpenRFIDPort(var Reader: TReader):boolean; var cRet : Integer; cBaud : Array[0..127] of AnsiChar; cTimeOut : Array[0..127] of AnsiChar; rBaudRate : AnsiString; rFrame : AnsiString; rTimeout : AnsiString; rTxTimeControl : AnsiString; rTxDelayTime : AnsiString; rCharTimeoutMpy : AnsiString;
begin Result:=True; cRet:=0; cBaud:=#0; cTimeOut:=#0; rBaudRate:=''; rFrame:=''; rTimeOut:=''; rTxTimeControl:=''; rTxDelayTime:=''; rCharTimeoutMpy:=''; cRet:=FECOM_DetectPort(Reader.iPortNr); if cRet = 0 then begin Reader.iPortHnd:=FECOM_OpenPort(PAnsiChar(IntToStr(Reader.iPortNr))); if Reader.iPortHnd >= 0 then begin rBaudRate:=IntToStr(Reader.iBaudRate); rFrame:=Reader.sFrame; rTimeout:=IntToStr(Reader.iTimeout); rTxTimeControl:=IntToStr(1); rTxDelayTime:=IntToStr(10); rCharTimeoutMpy:=IntToStr(5); cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'Baud', PAnsiChar(rBaudRate)); cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'Frame', PAnsiChar(rFrame)); cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'Timeout', PAnsiChar(rTimeout)); cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'TxTimeControl', PAnsiChar( rTxTimeControl)); cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'TxDelayTime', PAnsiChar( rTxDelayTime)); cRet:=FECOM_SetPortPara(Reader.iPortHnd, 'CharTimeoutMpy', PAnsiChar( rCharTimeoutMpy)); cRet:=FECOM_GetPortPara(Reader.iPortHnd, 'Baud', cBaud); cRet:=FECOM_GetPortPara(Reader.iPortHnd, 'Timeout', cTimeout); DisplayRFIDData('Baudrate : ' + cBaud); DisplayRFIDData('Timeout : ' + cTimeout); DisplayRFIDData('TxTimeControl : ' + rTxTimeControl); DisplayRFIDData('TxDelayTime : ' + rTxDelayTime); DisplayRFIDData('CharTimeoutMpy : ' + rCharTimeoutMpy); DisplayRFIDData('Frame : ' + rFrame); end else Result:=False; end else Result:=False; end; |
@bummi: Ja, die DLL's sind uralt, aber soweit ich weiss hat sich an der Funktionalität im Wesentlichen auch nichts großartiges geändert und
sie funktionieren noch immer, wenn nicht Embarcadero die Datentypen ändert...........
Viele Grüße
Chrissi
|
|
jaenicke
      
Beiträge: 19326
Erhaltene Danke: 1749
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 28.10.11 11:54
|
|
|