2012-04-13 7 views
1

Wie kann ich diese Zeile in C++ schreiben?Konvertieren Sie eine Delphi-Code-Zeile in C++

mit delphi-Code (Code nicht hier gepostet) Ich werde diesen Rekord mit ein paar Informationen gefüllt Datei schreiben und mit C++ Code exe wird i thhis Datensatz gelesen und die Informationen auf die Struktur übergeben

Dies ist der Code in delphi

type 
TSettings = record 
    sFileName: String[50]; 
    siInstallFolder: Byte; 
    bRunFile: Boolean; 
    ... 
    end; 

.. 
var 
i: dword; 
sZdData: PChar; 
Settings :Tsettings; 
begin 
.... 
    ZeroMemory(@Settings, sizeof(Tsettings)); 
     settings := Tsettings(Pointer(@sZdData[i])^); // this code to c++ 

C++ Code (hoffe, der Rest ist OK)

struct TSettings{ 
    char sFileName[50]; 
    byte siInstallFolder; 
    bool bRunFile; 
    ... 
} Settings; 

... 
DWORD i; 
LPBYTE sZdData; 

     ZeroMemory(&Settings, sizeof(TSettings)); 
     Settings = ????? // im failing here i dunno what to do // i need same as in delphi code above 

und sory für mein schlechtes Englisch .. :(

Dies ist der delphi Code

function GetInfoSettings(FileName: String; // filename from where to get data 
         var lpData: PChar; // where to write data 
         var dwSettingsLen: DWORD // returns the length of all bound files 
         ): Boolean; 
var 
    hFile: THandle; 
    DosHeader: TImageDosHeader; 
    NtHeaders: TImageNtHeaders; 
    SectionHeader: TImageSectionHeader; 
    dwReadBytes, dwOrginalFileSize, dwFileSize, dwSettingsLength: DWORD; 
begin 
    Result := False; 
    hFile := Createfile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); 
    SetFilePointer(hFile, 0, nil, FILE_BEGIN); 
    ReadFile(hFile, DosHeader, sizeof(DosHeader), dwReadBytes, nil); 
    if dwReadBytes = sizeof(DosHeader) then 
    begin 
    SetFilePointer(hFile, DosHeader._lfanew, nil, FILE_BEGIN); 
    ReadFile(hFile, NtHeaders, sizeof(NtHeaders), dwReadBytes, nil); 
    if dwReadBytes = sizeof(NtHeaders) then 
    begin 
     SetFilePointer(hFile, sizeof(SectionHeader) * (NtHeaders.FileHeader.NumberOfSections -1), nil, FILE_CURRENT); 
     ReadFile(hFile, SectionHeader, sizeof(SectionHeader), dwReadBytes, nil); 
     dwOrginalFileSize := SectionHeader.PointerToRawData + SectionHeader.SizeOfRawData; 
     dwFileSize := GetFileSize(hFile, nil); 
     dwSettingsLength := dwFileSize - dwOrginalFileSize; 
     if dwSettingsLength > 0 then 
     begin 
     SetFilePointer(hFile, dwOrginalFileSize, nil, FILE_BEGIN); 
     GetMem(lpData, dwSettingsLength); 
     ReadFile(hFile, lpData^, dwSettingsLength, dwReadBytes, nil); 
     if dwReadBytes = dwSettingsLength then 
     begin 
      Result := True; 
      dwSettingsLen := dwSettingsLength; 
     end; 
     end; 
    end; 
    end; 
    CloseHandle(hFile); 
end; 

und hier ich die Informationen oder die binded Datei bekommen ...

var i //, werden hier gespeichert werden, wie viel Bytes sind bereits getan .. dwDaSize: DWORD; // Länge der Daten nach allen Abschnitten .. dwFilenaam, sFileName: string; sZdData: PChar; vielleicht // hier werden alle Daten nach dem „EOF“ (Ende aller Abschnitte Daten) // der Dateiname sein, in dem die Datei extrahiert werden ..

Settings: Tsettings; 


// writting 
    hFile: THandle; 
    lpNumberOfBytesWritten: DWORD; 
begin 
    GetMem(dwFilenaam, MAX_PATH); 
    GetModuleFileName(GetModuleHandle(nil), dwFilenaam, MAX_PATH); 
    if GetInfos(dwFilenaam, sZdData, dwDaSize) then 
    begin 
    i := 0; 
    repeat 

     ZeroMemory(@Settings, sizeof(Tsettings)); 
     settings := Tsettings(Pointer(@sZdData[i])^); 

mein Versuch (ich weiß, dass dieser Code sieht Müll LOL) nicht?

bool getSettingsInfo(LPSTR FileName, LPBYTE lpdata, DWORD dwSettingsLen) 
{ 
    HANDLE HandleFile ; 
    DWORD dwReadBytes; 
    DWORD dwOrginalFileSize; 
    DWORD dwFileSize; 
    DWORD dwSettingsLength; 
    PIMAGE_DOS_HEADER pidh ; 
    PIMAGE_NT_HEADERS pinh ; 
    PIMAGE_SECTION_HEADER pish; 

    return false; 
    HandleFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, 0,OPEN_EXISTING,0, NULL); 
    SetFilePointer(HandleFile, 0,0, FILE_BEGIN); 
     ReadFile(HandleFile, pidh, sizeof(pidh), &dwReadBytes,NULL); 
    if (dwReadBytes == sizeof(pidh)) 
    { 
    SetFilePointer(HandleFile, pidh->e_lfanew , NULL, FILE_BEGIN); 
    ReadFile(HandleFile, pidh,sizeof(pinh), &dwReadBytes, NULL); 
    if (dwReadBytes == sizeof(pinh)) 
    { 
     SetFilePointer(HandleFile, sizeof(pish) * (pinh->FileHeader.NumberOfSections -1), NULL, FILE_CURRENT); 
     ReadFile(HandleFile, pish, sizeof(pinh), &dwReadBytes, NULL); 
     dwOrginalFileSize = pish->PointerToRawData + pish->SizeOfRawData; 
     dwFileSize = GetFileSize(HandleFile, NULL); 
     dwSettingsLength = dwFileSize - dwOrginalFileSize; 
     if (dwSettingsLength > 0) 
     { 

     SetFilePointer(HandleFile, dwOrginalFileSize, NULL, FILE_BEGIN); 
     realloc(lpdata, dwSettingsLength); 
     ReadFile(HandleFile, lpdata, dwSettingsLength, &dwReadBytes, NULL); 
     if (dwReadBytes == dwSettingsLength) 
     { 
     return true; 
      dwSettingsLen = dwSettingsLength; 
     } 
     } 
    } 
    } 
    CloseHandle(HandleFile); 
} 

Code zu extrahieren info ...

DWORD i; // here will be saved how much bytes are already done .. 
    DWORD dwDaSize; // length of data after all sections .. 

    LPSTR dwFilenaam; 
    LPBYTE sZdData; // here will be all data after "EOF" (End of all sections data) 
    LPSTR sFileName;// the filename where the file will be extracted .. 

    char * Installpath; 
    char * buffer; 

    HFILE hFile; 
    DWORD lpNumberOfBytesWritten; 

    memset(dwFilenaam,0, MAX_PATH); 
    GetModuleFileName(GetModuleHandle(NULL), dwFilenaam, MAX_PATH); 
    if (getSettingsInfo(dwFilenaam, sZdData, dwDaSize) == true) 
    { 
     i = 0; 
    // REPEAT 


     ZeroMemory(&Settings, sizeof(TSettings)); 

Settings = ??? 
+1

Delphi kurze Zeichenfolge (Zeichenfolge [50]) ist 51 Byte groß, da sFileName [0] die Länge der Zeichenfolge enthält. –

+0

+1 für den funky Code. –

+0

Sie müssen etwas von dem Code, den Sie weggelassen haben, mit '...' posten. Irgendwo wurde Inhalt mit einer Zuweisung zu "sZdData" zugewiesen, und in diesem fehlenden Code sind weitere Informationen verfügbar. –

Antwort

0
struct TSettings{ 
    uchar length ; // shortstrings have an implicit length byte 
    char sFileName[50]; 
    byte siInstallFolder; 
    bool bRunFile; // one byte, 1=true, 0=false any other value undefined 
    ... 
    } Settings; 


    DWORD i; 
    LPBYTE sZdData; 

    ZeroMemory(&Settings, sizeof(TSettings)); 

    literally it is something like 
    Settings = (struct Settings) (*((void *)&sZDData[i]) 

    essentially it does 

    memcpy (&sZDData[i],&settings,sizeof(TSettings)); 

Was sie tut, ist, um die Adresse des i-ten Elements von sZSdata (@sZDDATA [i]) und warf es zu ein untypisierter Zeiger. (Äquivalent in C++ (void *) (& sZDData [i])))

Dann kommt der flippige Teil, der es aufgibt (^ als Postfixoperator in Pascal, * als Präfixoperator in C) (im Wesentlichen das Ergebnis davon die Adresse, auf die der (void) ptr zeigt, ein Speicherblock, an den keine Längenangaben angehängt sind.

Wenn dies den Einstellungen zugewiesen ist, bedeutet dies scheinbar, dass Sie so viele Bytes wie die Größe der Lvalue (= sizeof (settings)) Bytes von dieser Adresse in den Lvalue (Einstellungen) verschieben.

Es ist ein sehr funky Konstrukt und ich bin mir nicht sicher, ob ich es vorher gesehen habe. Ich überprüfe auf beiden Ebenen in Delphi und FPC, und sie verhielten sich genauso.

+0

Dies ist nicht, was der Delphi-Code überhaupt tut, und es ist auch nicht, was der C++ - Code tun sollte. Es ist kein 'memcpy' beteiligt; es ist eine direkte Typumwandlung des Inhalts, auf den der Zeiger "sZdData" verweist, in einen Datensatz. IOW, es weist den Inhalt einer "TSettings" -Variable einem Speicherblock an der Adresse von 'sZdData [i] zu (erzeugt einen getippten Zeiger auf dieselbe Stelle). Es gibt überhaupt keine "Bewegung" oder "Kopie"; In dem Code, der gepostet wird, verweisen sowohl "Settings" als auch "sZdData [i]" auf denselben Speicherblock. –

+0

ive addes alle Code mybe es hilft euch Jungs zu verstehen, was ich brauche danke für die Antworten Jungs – user1332636

+0

Beachten Sie, dass die Post "im Wesentlichen" sagte. Es sollte für den Leser vereinfacht werden. In Wirklichkeit ist es Inline-Rep; movsd + movsw/b Statements, wenn nötig, aber ich weiß nicht, wie man das für C zeigt. Und deine Beschreibung ist falsch. Es weist den Inhalt des Blocks/TO/den TSettings-Wert zu, nicht umgekehrt. In dem Code, den ich sah (vor den Hinzufügungen), gab es keine Möglichkeit herauszufinden, was szddata auch zeigt. Ich nahm an, dass es sich um einen nicht verwandten Dateipuffer handelte. –

0

Es sollte als Delphi in C leichter sein:

typedef struct 
{ 
    uchar length ; // shortstrings have an implicit length byte 
    char sFileName[50]; 
    byte siInstallFolder; 
    bool bRunFile; // one byte, 1=true, 0=false any other value undefined 
    ... 
} TSettings; 

TSettings settings; 
DWORD i; 
LPBYTE sZdData; 

settings = *(TSettings*)(&sZdData[i]); 

Diese Memcpy nennen, nicht wegen Gießen, weil der Zuordnung TSettings Struktur. Sie können, ohne zu kopieren zugreifen, wenn Sie Zeiger auf TSettings verwenden:

TSettings* pSettings; 
DWORD i; 
LPBYTE sZdData; 

pSettings = (TSettings*)(&sZdData[i]); 
printf("%d\n", pSettings->siInstallFolder); // example 

By the way, für die Ausrichtung vorsichtig sein. Die Gesamtgröße der Struktur kann aufgrund von Lücken zwischen den Elementen Ihre Erwartungen übersteigen.

+0

Übrigens akzeptieren fast alle 32/64-Bit-Compiler das Äquivalent Ihres Codes auch in Pascal . Das Beispiel ist verschachtelt. –

Verwandte Themen