![]() |
Einem Array of WChar einen String zuweisen
Hallo
wie kann ich diesem Array einfach einen String zuweisen :roll:
Delphi-Quellcode:
dann in etwa:
type
DATA_1 = record sztPortName : Array[0..63] of [b]WChar[/b]; end; TData = DATA_1;
Delphi-Quellcode:
Es muss ja auch noch eine Umwandlung in WChar stattfinden!
TData.sztPortName := 'PortName';
Vielen Dank schon mal |
Re: Einem Array of WChar einen String zuweisen
Hallo s14,
sieh mal in der OH unter StringToWideChar nach. BTW TData ist ein ungewöhlicher Variablenname und sollte umbenannt werden, um keine Verwechslungen mit einem Datentyp aufkommen zu lassen... |
Re: Einem Array of WChar einen String zuweisen
@choose,
StrinToWideChar gibt aber doch nur einen Zeiger und kein WChar zurück :?: TData ist allerdings unglücklich, stimmt. Der Typ heist ja im Programm auch anders, ich hab das nur schnell getippt um das Problem zu verdeutlichen :wink: Gruß |
Re: Einem Array of WChar einen String zuweisen
Aus der OH zu StringToWideChar:
Zitat:
|
Re: Einem Array of WChar einen String zuweisen
Delphi-Quellcode:
[add]
Type TData = Record
sztPortName: Array[0..63] of WChar; End; Var S: String; WS: TData; StringToWideChar(S, @WS, Min(Length(S) + 1, 64)); Wenn der String (S) immer mindestens 63 Zeichen lang ist, dann geht auch das:
Delphi-Quellcode:
StringToWideChar(S, @WS, 64);
http://www.delphipraxis.net/images/common/divider.jpg ![]() ![]() ![]() |
Re: Einem Array of WChar einen String zuweisen
Liste der Anhänge anzeigen (Anzahl: 1)
Vielen Dank für die Antworten!
Ich komme da aber einfach nicht weiter. Vielleicht ist ja schon bei der Übersetzung aus dem DDK ein Fehler passiert :roll: Hier mal meine Übersetzung der Datei tcpxcv.h:
Delphi-Quellcode:
Der Aufruf sieht dann so aus:
unit Port;
// aus dem DDK -> tcpxcv.h interface uses winspool, windows; const MAX_PORTNAME_LEN = 63 +1; // port name length MAX_NETWORKNAME_LEN = 48 +1; // host name length MAX_SNMP_COMMUNITY_STR_LEN = 32 +1; // SNMP Community String Name MAX_QUEUENAME_LEN = 32 +1; // lpr print que name MAX_IPADDR_STR_LEN = 15 +1; // ip address; string version PROTOCOL_RAWTCP_TYPE = 1; MAX_DEVICEDESCRIPTION_STR_LEN = 256+1; type _PORT_DATA_1 = record sztPortName : Array[0..MAX_PORTNAME_LEN] of WChar; dwVersion, dwProtocol, cbSize, dwReserved : Cardinal; sztHostAddress : Array[0..MAX_NETWORKNAME_LEN] of WChar; sztSNMPCommunity : Array[0..MAX_SNMP_COMMUNITY_STR_LEN] of WChar; dwDoubleSpool : Cardinal; sztQueue : Array[0..MAX_QUEUENAME_LEN] of WChar; sztIPAddress : Array[0..MAX_IPADDR_STR_LEN] of WChar; Reserved : Array[0..540] of Byte; dwPortNumber, dwSNMPEnabled, dwSNMPDevIndex : Cardinal; end; PPortData1 = ^_PORT_DATA_1; TPortData1 = _PORT_DATA_1; _DELETE_PORT_DATA_1= record psztPortName : Array[0..MAX_PORTNAME_LEN] of WChar; Reserved : Array[0..98] of Byte; dwVersion : Cardinal; dwReserved : Cardinal; end; PDeletePortData1 = ^_DELETE_PORT_DATA_1; TDeletePortData1 = _DELETE_PORT_DATA_1; _CONFIG_INFO_DATA_1 = record Reserved : Array[0..128] of Byte; dwVersion : Cardinal; end; PConfigInfoData = ^_CONFIG_INFO_DATA_1; TConfigInfoData = _CONFIG_INFO_DATA_1; function XcvData(hXcv: Cardinal; pszDataName: LPCWSTR;//PWideChar; pInputData: Pointer; cbInputData: Cardinal; pOutputData: PBYTE; cbOutputData: Cardinal; pcbOutputNeeded: PDWORD; pdwStatus: PDWORD): Boolean; stdcall; // aus MSDN {BOOL WINAPI XcvData( HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PDWORD pdwStatus ); } implementation function XcvData; external winspl name 'XcvDataW'; end.
Delphi-Quellcode:
OpenPrinter funktioniert noch aber eben der Aufruf der Funktion XcvData nicht :wall:
// uses Math, Port
procedure TForm1.Button1Click(Sender: TObject); var hXcv : THandle; pDefaults : PPrinterDefaults; pInputData : PChar; pdwStatus : PDWORD; PortData1 : TPortData1; sPortName, sHostAddress, sSNMPCommunity, sQueue, sIPAddress : String; begin // ("<ServerName>\\,XcvMonitor <MonitorName>", für Remotezugriff !! GetMem(pDefaults, SizeOf(TPrinterDefaults)); pDefaults.pDatatype := NIL; pDefaults.pDevMode := NIL; pDefaults.DesiredAccess := SERVER_ACCESS_ADMINISTER;//SERVER_ALL_ACCESS;//PRINTER_ACCESS_ADMINISTER; // cltprinter01 if OpenPrinter(',XcvMonitor Standard TCP/IP Port', hXcv, nil) then begin // -- Handle erhalten m.Lines.Add('hXcv erhalten -> ' + IntToStr(hXcv)); // -- Struktur erstellen sPortName := 'IP_222.222.222.222'; sHostAddress := '222.222.222.222'; sSNMPCommunity := 'public'; sQueue := ''; sIPAddress := '222.222.222.222'; FillChar(PortData1, SizeOf(TPortData1), #0); StringToWideChar(sPortName, @PortData1.sztPortName, Min(Length(sPortName) +1, MAX_PORTNAME_LEN)); PortData1.dwVersion := 1; PortData1.dwProtocol := PROTOCOL_RAWTCP_TYPE; PortData1.cbSize := SizeOf(TPortData1); Portdata1.dwReserved := 0; StringToWideChar(sHostAddress, @PortData1.sztHostAddress, Min(Length(sHostAddress) +1, MAX_NETWORKNAME_LEN)); StringToWideChar(sSNMPCommunity, @PortData1.sztSNMPCommunity, Min(Length(sSNMPCommunity) +1, MAX_SNMP_COMMUNITY_STR_LEN)); PortData1.dwDoubleSpool := 0; StringToWideChar(sQueue, @PortData1.sztQueue, Min(Length(sQueue) +1, MAX_QUEUENAME_LEN)); StringToWideChar(sIPAddress, @PortData1.sztIPAddress, Min(Length(sIPAddress) +1, MAX_IPADDR_STR_LEN)); PortData1.dwPortNumber := 9100; PortData1.dwSNMPEnabled := 0; PortData1.dwSNMPDevIndex := 1; New(pdwStatus); // !!! dieser Aufruf funktioniert NICHT !!! Rückgabe "Ungültiger Parameter" if XcvData(hXcv, // Handle des Monitors 'L"AddPort"', // Befehl an DLL, DeletePort auch möglich @PortData1, // PORT_DATA_1 Struktur SizeOf(PortData1), // Größe des Puffers nil, 0, nil, // not used pdwStatus) then begin m.Lines.Add('XcvData "AddPort" erfolgreich ausgeführt'); end else m.Lines.Add('Error XcvData -> ' + SysErrorMessage(GetLastError)); m.Lines.Add('pdwStatus -> ' + SysErrorMessage(pdwStatus^)); ClosePrinter(hXcv); end else m.Lines.Add('Error OpenPrinter -> ' + SysErrorMessage(GetLastError)); FreeMem(pDefaults); end; Als Anhang hab ich noch die Headerdatei eingefügt. Es wäre schön wenn einer einen Fehler finden würde oder auch sonst irgendeinen Hinweis geben kann!! Gruß s14 |
Re: Einem Array of WChar einen String zuweisen
Header-Konversionen sind mein Fall.
Ich schau mir das mal spaeter genauer an. 1. Immer "packed record". 2. nicht "Array[0..MAX_PORTNAME_LEN] of WChar;" sondern "Array[0..MAX_PORTNAME_LEN-1] of WChar;" |
Re: Einem Array of WChar einen String zuweisen
Ein Hallöle von
![]() das wurde ja schon gesagt:
Code:
Das mit der Header-Übersetzung lasse ich lieber Robert machen.
[b]type[/b]
[color=olive]xxx[/color] = [b][color=red]packed[/color] record[/b] [color=olive]xxx[/color]: [b]Array[/b][0..MAX_[color=olive]xxx[/color] [color=red][b]- 1[/b][/color]] [b]of[/b] [color=olive]xxx[/color]; Dabei breche ich mir auch immer was ab. ![]() Die Typen WChar und PWChar sind nur durch die Übersetzung und Implementierung von WINDEF.H in Delphi vorhanden, die Pascal/Delphi-Typen sind WideChar und PWideChar. Für den Type DWord (DoubleWord) ist der fundamentale Integer-Type LongWord besser als der generische Integer-Type Cardinal. (die generischen Typen Cardinal und Integer sind an die Entwicklungsumbebung angepasst und "rein zufällig" zur Zeit 32 Bit, so wie das 32 Bit-DWord - auf einem 64 Bit System sind diesen dann auch mal schnell 64 Bit lang) Das mit StringToWideChar sieht alles in Ordnung aus.
Code:
FillChar ist zwar nicht unbedingt erforderlich, kann aber auch nicht schaden. Und wenn die Prozeduren, an die diese übergeben werden, nicht ganz sauber arbeiten, kann es sogar hilfreich sein.
FillChar([color=olive]ArrayOfWideChar[/color], SizeOf([color=olive]ArrayOfWideChar[/color]), #0);
StringToWideChar([color=olive]String[/color], @[color=olive]ArrayOfWideChar[/color], Min(Length([color=olive]String[/color]) + 1, [color=olive]ArrayOfWideChar_Größe[/color])); [add] Hier liegt aber auch noch ein Fehler vor:
Code:
http://www.delphipraxis.net/images/common/divider.jpg
XcvData(
HANDLE hXcv, LPCWSTR pszDataName, [color=gray]*[/color] PBYTE pInputData, DWORD cbInputData, [color=gray]*[/color] PBYTE pOutputData, DWORD cbOutputData, [color=gray]*[/color] PDWORD pcbOutputNeeded, [color=gray]*[/color] [color=red]P[/color]DWORD pdwStatus) XcvData( hXcv, 'L"AddPort"', [color=gray]*[/color] @PortData1, SizeOf(PortData1), [color=gray]*[/color] nil, 0, [color=gray]*[/color] nil, [color=gray]*[/color] [color=red]@[/color]pdwStatus) [color=gray]*[/color] = Zeiger ![]() ![]() ![]() |
Re: Einem Array of WChar einen String zuweisen
Also ich benutze immer DWORD wie es in Windows.pas deklariert ist.
Genau fuer die Windows APIs ist das naemlich da. |
Re: Einem Array of WChar einen String zuweisen
@Robert: Gut, darüber kann man sich streiten
![]() Und ich bin ja nicht gerade ein Engel, der immer alles so nimmt, wie es ist. ![]() Zitat:
Fest steht aber, das DWord und LongWord immer 32 Bit lang sind, und Cardinal an die zugrundeliegende CPU und das Betriebssystem angepasst ist. (wenn also das Programm auf einem 16 Bit oder 64 Bit System compiliert wird, geht der Code nicht mehr) Zitat:
Zitat:
![]() ![]() ![]() |
Re: Einem Array of WChar einen String zuweisen
So ich habe mir mal die Datei aus dem Win XP DDK zur Brust genommen.
Ich hab jetzt keine Lust dem ganzen API nachzurennen. XcvData ist z. B. nicht darin deklariert. Die obigen Konversionen sind soweit richtig bis auf die erwaehnten Fehler. Extra Typen mit Delphi-like Namen hab ich auch nicht gemacht.
Delphi-Quellcode:
{*++
Copyright (c) 1997 - 1999 Hewlett-Packard Company. Copyright (c) 1997 - 1999 Microsoft Corporation All rights reserved Module Name: tcpxcv.h --*} unit tcpxcv; interface uses Windows; const RAWTCP = 1; PROTOCOL_RAWTCP_TYPE = RAWTCP; LPR = 2; PROTOCOL_LPR_TYPE = LPR; MAX_PORTNAME_LEN = 63 +1; // port name length MAX_NETWORKNAME_LEN = 48 +1; // host name length MAX_SNMP_COMMUNITY_STR_LEN = 32 +1; // SNMP Community String Name MAX_QUEUENAME_LEN = 32 +1; // lpr print que name MAX_IPADDR_STR_LEN = 15 +1; // ip address; string version MAX_ADDRESS_STR_LEN = 12 +1; // hw address length MAX_DEVICEDESCRIPTION_STR_LEN = 256+1; type PPORT_DATA_1 = ^PORT_DATA_1; PORT_DATA_1 = packed record sztPortName: array [0..MAX_PORTNAME_LEN-1] of WideChar; dwVersion: DWORD; dwProtocol: DWORD; cbSize: DWORD; dwReserved: DWORD; sztHostAddress: array [0..MAX_NETWORKNAME_LEN-1] of WideChar; sztSNMPCommunity: array [0..MAX_SNMP_COMMUNITY_STR_LEN-1] of WideChar; dwDoubleSpool: DWORD; sztQueue: array [MAX_QUEUENAME_LEN-1] of WideChar; sztIPAddress: array [MAX_IPADDR_STR_LEN-1] of WideChar; Reserved: array [0..539] of Byte; dwPortNumber: DWORD; dwSNMPEnabled: DWORD; dwSNMPDevIndex: DWORD; end; PDELETE_PORT_DATA_1 = ^DELETE_PORT_DATA_1; DELETE_PORT_DATA_1 = packed record psztPortName: array [0..MAX_PORTNAME_LEN-1] of WideChar; Reserved: array [0..97] of Byte; dwVersion: DWORD; dwReserved: DWORD; end; PCONFIG_INFO_DATA_1 = ^CONFIG_INFO_DATA_1; CONFIG_INFO_DATA_1 = packed record Reserved[0..127] of Byte; dwVersion: DWORD; end; implementation end. |
Re: Einem Array of WChar einen String zuweisen
Vielen Dank an alle :dp:
Es funktioniert (fast) alles @Robert Marquardt In _PORT_DATA_1 muss die Länge mit
Delphi-Quellcode:
angegeben werden, frag mich nicht warum, ist so :roll:
Reserved : Array[0..541] of Byte;
Vielleicht ein Fehler in der Dokumentation? Ach ja zur Info der Aufruf der Funktion muss so aussehen:
Delphi-Quellcode:
Also AddPort, nicht wie in der Doku L"AddPort".
XcvData(hXcv, // Handle des Monitors
'AddPort', // Befehl an DLL, DeletePort auch möglich @PortData1, // PORT_DATA_1 Struktur SizeOf(PortData1)+2, // Größe des Puffers nil, 0, // not used @OutputNeeded, @pdwStatus) Mein Problem ist jetz nur noch der Remote-Aufruf der Funktion OpenPrinter. Das sollte laut MSDN so aussehen:
Delphi-Quellcode:
Funktioniert aber nicht, vielleicht weiß da ja noch jemand was :drunken:
// Handle to a remote machine
if (OpenPrinter("<ServerName>\\,XcvMonitor <MonitorName>", &hXcv, &Defaults ) { // hXcv contains an Xcv data handle to the monitor // <MonitorName> on the server <ServerName> } Viele Grüße s14 |
Re: Einem Array of WChar einen String zuweisen
541 statt 539 ist wirklich ungewoehnlich.
Da hat sich seit dem Win 98 DDK nichts geaendert (wohl dem der sowas noch hat). L"AddPort" ist ein Unicode-String-Literal (ein "Long"-Prefix). Die Umwandlung macht Delphi aber automatisch wenn der Parameter auf PWideChar lautet. |
Re: Einem Array of WChar einen String zuweisen
Ein Hallöle von
![]() also dan so:
Code:
z.B.:
XcvData(
[color=gray]*[/color] HANDLE hXcv, [color=gray]*[/color] LPCWSTR pszDataName, [color=gray]*[/color] PBYTE pInputData, DWORD cbInputData, [color=gray]*[/color] PBYTE pOutputData, DWORD cbOutputData, [color=gray]*[/color] PDWORD pcbOutputNeeded, [color=gray]*[/color] PDWORD pdwStatus) XcvData( [color=gray]*[/color] hXcv, [color=gray]*[/color] @DataName, [color=gray]*[/color] @InputData, SizeOf(InputData), [color=gray]*[/color] @OutputData, SizeOf(OutputData), [color=gray]*[/color] @OutputNeeded, [color=gray]*[/color] @dwStatus) [color=gray]*[/color] = Zeiger
Delphi-Quellcode:
http://www.delphipraxis.net/images/common/divider.jpg
Const MAX_DATANAME = XXX; {weiß nicht wie lang es sein muß}
Var DataName: Array[0..MAX_DATANAME - 1] of WideChar; StringToWideChar('AddPort', @DataName, Min(Length('AddPort') + 1, MAX_DATANAME)); XcvData( hXcv, @DataName, @PortData1, SizeOf(PortData1), nil, 0, nil, @pdwStatus) ![]() ![]() ![]() |
Re: Einem Array of WChar einen String zuweisen
Hi,
leider habe ich bisher keinen Erfolg gehabt beim Erzeugen eines TCP Ports. Die Ausführung von XcvData scheint zunächst zu funktionieren, jedoch erhalte ich einen anschließend ein "Zugriff verweigert" und der Port wurde doch nicht angelegt. DIe Rechte die ich dem Defaults vergeben hatte waren SERVER_ACCESS_ADMINISTER. Also eigentlich sollte es doch genug sein. Das ganze passiert unter Win XP pro mit Admin Rechten. :pale: Irgendeine Idee wo ich den Fehler machen? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz