Toon posts:

[Delphi .NET] Unsafe code, wil nie compileren

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben een beetje aan het spelen met het migreren van Delphi 7 projecten naar Delphi .NEt. Tot nu toe ging alles "vlekkeloos", maar ik wil nu graag dat ik unsafe code compileer in Delphi .NET.

Nu heb ik natuurlijk al wat gezocht op internet, en dan zou de volgende oplossing moeten werken:

Delphi:
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
{$UNSAFECODE ON}
procedure TForm1.Test; unsafe;
var
  charPtr: PChar; // PChar is unsafe type
begin
  // reserveer opslagruimte voor 4 characters (UNSAFE CODE)
  GetMem(charPtr, 4 * SizeOf(Char));

  // waardes toekennen
  charPtr^ := 'A';
  Inc(charPtr);
  charPtr^ := 'B';
  Inc(charPtr);
  charPtr^ := 'C';
  Inc(charPtr);
  charPtr^ := #0;  // String terminator

  // weergeven van de waardes
  Dec(charPtr, 3);
  ShowMessage('Characters stored = '+charPtr);


  // vrijgeven van geheugen (UNSAFE CODE)
  FreeMem(charPtr);
end;
{$UNSAFECODE OFF}


Maar dit levert tijdens compileren de volgende errors:

[Error] Unit1.pas(32): Undeclared identifier: 'GetMem'
[Error] Unit1.pas(45): Incompatible types: 'string' and 'PWideChar'
[Error] Unit1.pas(49): Undeclared identifier: 'FreeMem'

En dan natuurlijk de laatste FATAL ERROR:

[Fatal Error] Project1.dpr(7): Could not compile used unit 'Unit1.pas'


Nu weet ik niet precies wrom het fout gaat, volgens de voorbeelden op inet zou dit gewoon moeten werken. Iemand die me op weg kan helpen?

Verwijderd

Verwijderd schreef op vrijdag 21 januari 2005 @ 20:41:
Nu heb ik natuurlijk al wat gezocht op internet, en dan zou de volgende oplossing moeten werken:

Delphi:
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
{$UNSAFECODE ON}
procedure TForm1.Test; unsafe;
var
  charPtr: PChar; // PChar is unsafe type
begin
  // reserveer opslagruimte voor 4 characters (UNSAFE CODE)
  GetMem(charPtr, 4 * SizeOf(Char));

  // waardes toekennen
  charPtr^ := 'A';
  Inc(charPtr);
  charPtr^ := 'B';
  Inc(charPtr);
  charPtr^ := 'C';
  Inc(charPtr);
  charPtr^ := #0;  // String terminator

  // weergeven van de waardes
  Dec(charPtr, 3);
  ShowMessage('Characters stored = '+charPtr);


  // vrijgeven van geheugen (UNSAFE CODE)
  FreeMem(charPtr);
end;
{$UNSAFECODE OFF}


Maar dit levert tijdens compileren de volgende errors:

[Error] Unit1.pas(32): Undeclared identifier: 'GetMem'
[Error] Unit1.pas(45): Incompatible types: 'string' and 'PWideChar'
[Error] Unit1.pas(49): Undeclared identifier: 'FreeMem'

En dan natuurlijk de laatste FATAL ERROR:

[Fatal Error] Project1.dpr(7): Could not compile used unit 'Unit1.pas'


Nu weet ik niet precies wrom het fout gaat, volgens de voorbeelden op inet zou dit gewoon moeten werken. Iemand die me op weg kan helpen?
Het kan zijn dat ik wat dingen door elkaar haal, omdat ik Delphi 2005 nog niet volledig doorgenomen heb.

Ben je met een win32-applicatie bezig of een .net-applicatie?
GetMem en FreeMem is onbekend. Mijn eerste gedachte is dan dat je wellicht een unit ofzo bent vergeten te declareren.
Vervang PChar door Stringbuilder.
Deze code is inderdaad unsafe! Waar is de try... finally ... end?

Verwijderd

Topicstarter
Verwijderd schreef op vrijdag 21 januari 2005 @ 20:58:
[...]

Het kan zijn dat ik wat dingen door elkaar haal, omdat ik Delphi 2005 nog niet volledig doorgenomen heb.

Ben je met een win32-applicatie bezig of een .net-applicatie?
GetMem en FreeMem is onbekend. Mijn eerste gedachte is dan dat je wellicht een unit ofzo bent vergeten te declareren.
Vervang PChar door Stringbuilder.
Deze code is inderdaad unsafe! Waar is de try... finally ... end?
Ik heb een win32 applicatie die ik wil migreren naar een .NET applicatie.

GetMem en FreeMem horen vervangen te worden in .NET door New en Dispose, maar dat is nu juist NIET de bedoeling. Het moet mogelijk zijn om in een Delphi .NET applicatie deze te gebruiken samen met PChar, ook al is het dan unsafe wat je als executable zou krijgen, mbv. van de desbetreffende compiler directives: {$UNSAFECODE ON} en {$UNSAFECODE OFF}

Ik weet ook dat de String of StringBuilder als vervanger dient van PChar in Delphi .NET, maar zoals nu hopelijk duidelijk zal zijn is het mijn bedoeling om de code unsafe te kunnen compileren.

Desondanks, denk ik dat je toch enigzins gelijk hebt:

Want GetMem en FreeMem komen uit de Win32 wereld, en bevinden zich in de unit SysUtils. Deze is ook in de uses clausule opgenomen, en veroorzaakt verder geen foutmeldingen. Waarschijnlijk staat GetMem en FreeMem dan niet in deze unit van Delphi .NET? Als dit het geval is, kan ie idd niet compileren. Maar hoe lost men dit dan alsnog op?

En dan is er nog het PChar verhaal. Wrom gaat dit niet goed?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Delphi heeft die functies gewoon niet meer in .Net. Een juiste oplossing hangt af van jouw code en dat is volgens mij niet de code die je hier hebt laten zien. New en Dispose kunnen werken, evenals een StringBuilder, een Dynamic Array of classes.

Je tweede probleem komt omdat je PChar in .Net automatisch een PWideChar is. Evenals een string eigenlijk een WideString is in .Net. En Delphi for .Net heeft niet de mogelijkheid gemaakt om een PWideChar samen te voegen met een WideString. Dat laatste was geen probleem onder win32. Waarschijnlijk heeft men dit niet gedaan omdat de code toch al eigenlijk niet voor hoort te komen. Het is tenslotte unsafe en dat is nou net niet het idee van .Net. De onderstaande code werkt, maar ik zou er gewoon helemaal van afzien om wat voor unsafe code te gebruiken dan ook. Waarom zou je naar .Net overgaan als je toch niet helemaal doet?!
Delphi:
1
ShowMessage('Characters stored = '+charPtr^); 

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
LordLarry schreef op zaterdag 22 januari 2005 @ 00:23:
Delphi heeft die functies gewoon niet meer in .Net. Een juiste oplossing hangt af van jouw code en dat is volgens mij niet de code die je hier hebt laten zien. New en Dispose kunnen werken, evenals een StringBuilder, een Dynamic Array of classes.

Je tweede probleem komt omdat je PChar in .Net automatisch een PWideChar is. Evenals een string eigenlijk een WideString is in .Net. En Delphi for .Net heeft niet de mogelijkheid gemaakt om een PWideChar samen te voegen met een WideString. Dat laatste was geen probleem onder win32. Waarschijnlijk heeft men dit niet gedaan omdat de code toch al eigenlijk niet voor hoort te komen. Het is tenslotte unsafe en dat is nou net niet het idee van .Net. De onderstaande code werkt, maar ik zou er gewoon helemaal van afzien om wat voor unsafe code te gebruiken dan ook. Waarom zou je naar .Net overgaan als je toch niet helemaal doet?!
Delphi:
1
ShowMessage('Characters stored = '+charPtr^); 
Hmm, dus GetMem em FreeMem zijn NIET meer te gebruiken in Delphi .NET ongeacht ik aangeef dat het unsafe code is. OK, kan ik nog mee leven. En PChar in Win32 en PWideChar, dat wist ik dus niet en moet ik me dan maar bij neer leggen.
Maar wil nog wel even duidelijk stellen dat ik weet dat het beter is om safe code te schrijven in Delphi .NET en dat mijn doel dus was om toch eens te proberen om unsafe code in Delphi .NET te schrijven. Dit puur en alleen om te testen. Heeft iemand misschien nog een voorbeeld van unsafe code die compileerbaar is in Delphi .NET ?

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Je kunt pointers gebruiken zoals jij doet met PChar, alleen het probleem is dat je sowieso eerst een gewone array van PChar's moet aanmaken. Vervolgens moet je, als je met die array gaat werken, aangeven dat ie tijdelijk op z'n plaats moet blijven staan in geheugen. In C# doe je dat met fixed, in C++ met een pinning pointer. Misschien dat als je daarop zoekt, dat je een magisch keyword voor Delphi vindt dat hetzelfde doet.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


Verwijderd

Deze compiler directive is op dit punt volgens mij overbodig.
Verwijderd schreef op vrijdag 21 januari 2005 @ 20:41:
Nu weet ik niet precies wrom het fout gaat, volgens de voorbeelden op inet zou dit gewoon moeten werken. Iemand die me op weg kan helpen?
Undocumented Delphi 8 compiler directive UNSAFECODE - Part 2

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 12:21

alienfruit

the alien you never expected

Hey! Sinds wanneer heeft Chee Wee een blog :D Altijd lol met Chee Wee :X

[ Voor 24% gewijzigd door alienfruit op 22-01-2005 20:32 ]

Pagina: 1