AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Einem Array of WChar einen String zuweisen
Thema durchsuchen
Ansicht
Themen-Optionen

Einem Array of WChar einen String zuweisen

Ein Thema von s14 · begonnen am 9. Dez 2003 · letzter Beitrag vom 7. Mär 2004
Antwort Antwort
Seite 1 von 2  1 2      
s14

Registriert seit: 15. Mai 2003
Ort: München
251 Beiträge
 
Delphi 7 Architect
 
#1

Einem Array of WChar einen String zuweisen

  Alt 9. Dez 2003, 16:02
Hallo
wie kann ich diesem Array einfach einen String zuweisen

Delphi-Quellcode:
type
  DATA_1 = record
    sztPortName : Array[0..63] of [b]WChar[/b];
  end;
  TData = DATA_1;
dann in etwa:
TData.sztPortName := 'PortName'; Es muss ja auch noch eine Umwandlung in WChar stattfinden!

Vielen Dank schon mal
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#2

Re: Einem Array of WChar einen String zuweisen

  Alt 9. Dez 2003, 16:08
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...
gruß, choose
  Mit Zitat antworten Zitat
s14

Registriert seit: 15. Mai 2003
Ort: München
251 Beiträge
 
Delphi 7 Architect
 
#3

Re: Einem Array of WChar einen String zuweisen

  Alt 9. Dez 2003, 16:19
@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

Gruß
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#4

Re: Einem Array of WChar einen String zuweisen

  Alt 9. Dez 2003, 16:32
Aus der OH zu StringToWideChar:
Zitat von OH:
[...]
Dest ist der Puffer, in den der entsprechende UNICODE-String geschrieben wird. Die Größe des Puffers wird mit dem Parameter DestSize festgelegt. Nach dem Aufruf von StringToWideChar enthält Dest höchstens DestSize - 1 Zeichen (einschließlich eines abschließenden NULL-Zeichens).
[...]
StringToWideChar gibt einen Zeiger auf Dest zurück.
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#5

Re: Einem Array of WChar einen String zuweisen

  Alt 9. Dez 2003, 16:36
Delphi-Quellcode:
Type TData = Record
  sztPortName: Array[0..63] of WChar;
End;

Var S: String;
  WS: TData;



StringToWideChar(S, @WS, Min(Length(S) + 1, 64));
[add]
Wenn der String (S) immer mindestens 63 Zeichen lang ist, dann geht auch das:
StringToWideChar(S, @WS, 64);

http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
s14

Registriert seit: 15. Mai 2003
Ort: München
251 Beiträge
 
Delphi 7 Architect
 
#6

Re: Einem Array of WChar einen String zuweisen

  Alt 10. Dez 2003, 08:20
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

Hier mal meine Übersetzung der Datei tcpxcv.h:
Delphi-Quellcode:
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.
Der Aufruf sieht dann so aus:
Delphi-Quellcode:
// 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;
OpenPrinter funktioniert noch aber eben der Aufruf der Funktion XcvData nicht

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
Angehängte Dateien
Dateityp: h tcpxcv.h (2,0 KB, 19x aufgerufen)
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#7

Re: Einem Array of WChar einen String zuweisen

  Alt 10. Dez 2003, 10:58
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;"
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#8

Re: Einem Array of WChar einen String zuweisen

  Alt 10. Dez 2003, 11:51
Ein Hallöle von http://www.FrankNStein.de/Smiley-Wolke2.gif,

das wurde ja schon gesagt:
Code:
[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];
Das mit der Header-Übersetzung lasse ich lieber Robert machen.
Dabei breche ich mir auch immer was ab. http://www.FrankNStein.de/Smiley-Krank.gif

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([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]));
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.

[add]
Hier liegt aber auch noch ein Fehler vor:
Code:
  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

http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#9

Re: Einem Array of WChar einen String zuweisen

  Alt 10. Dez 2003, 14:23
Also ich benutze immer DWORD wie es in Windows.pas deklariert ist.
Genau fuer die Windows APIs ist das naemlich da.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#10

Re: Einem Array of WChar einen String zuweisen

  Alt 10. Dez 2003, 14:56
@Robert: Gut, darüber kann man sich streiten http://www.FrankNStein.de/Smiley-quasseln.gif , da DWord und LongWord das Selbe sind.
Und ich bin ja nicht gerade ein Engel, der immer alles so nimmt, wie es ist. http://www.FrankNStein.de/Smiley-immerlieb.gif
Zitat von meine Signatur (auch wenn sie derzeit nicht da ist):
warum einfach wenn's auch kompliziert geht
schreib wie du willst und halt dich an keine standards

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 von Unit Windows:
type
{ Translated from WINDEF.H }
* DWORD = Types.DWORD;
Zitat von Unit Types:
type
* DWORD = LongWord;

http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz