Czy ktoś wie gdzie można znaleźć przykłady przerabiania funkcji korzystających ze wskaźników na wersję .NET
Nie chodzi mi o
{%UNSAFECODE ON}
;-P
Czy ktoś wie gdzie można znaleźć przykłady przerabiania funkcji korzystających ze wskaźników na wersję .NET
Nie chodzi mi o
{%UNSAFECODE ON}
;-P
nie wiem czy się nie zbłaźnię, ale wskaźniki według mojego laickiego rozumowania to po prostu bezpośredni dostęp do pamięci. Zamiast odwoływać się do zmiennych odwołujesz się do konkretnych adresów w pamięci, co zwiększa szybkość działania programu.
Przerób program na korzystanie ze zmiennych :)
Jeśli sie mylę poprawcie mnie i doedukujcie :]
SebaZ napisał(a)
nie wiem czy się nie zbłaźnię, ale wskaźniki według mojego laickiego rozumowania to po prostu bezpośredni dostęp do pamięci.
Oczywiście że tak, ale problem jest gdy trzeba skorzystać z np. komuniaktów
procedure RE_SetLineSpacing(ARichEdit: TRichEdit; lineSpacing: Byte);
var
pf2: ParaFormat2;
begin
FillChar(pf2, SizeOf(pf2), 0);
pf2.cbSize := SizeOf(PARAFORMAT2);
pf2.dwMask := PFM_LINESPACING;
pf2.bLineSpacingRule := lineSpacing;
SendMessage(ARichEdit.Handle, EM_SETPARAFORMAT, 0, Longint(@pf2));
end;
co wtedy [???]
W książce Boduch pisze że do tego służy klasa marshal ale słabo to opisał, dlatego szukam przykładów.
A może ktoś wie jak pobrać adres komórki pamięci np. w której się zanjduje pf2 z powyższego przykładu, bo chyba na to wskazuje @pf2, tak sądzą ale może się mylę.
a słyszałes o unsafe ?
Mimo że w pierwszym poscie pisałem że nie chodzi o unsafe to dzieki za linka, trochę rzeczy mi wyjaśnił :-)
ale gdy korzystam z unsafe to wywala mi błąd Invalid typecast przy:
Integer(@pf2)
</b>
więc jak mam zrzutować wskaźnik na integer ??
LongInt(@pf2)
chyba?
obojętne czy LongInt czy Integer błąd wyskakuje ten sam ;-P
nie wiem w jakim formacie jest adres w pamięci, ale trzeba pewnie przekonwertować. Widocznie rzutowanie jest niemozliwe :)
Filozuję już, ale moja skromna wiedza nie widzi na razie rozwiązania problemu.
W c# twój kod wyglądałby mniej więcej w ten sposób:
PARAFORMAT2 pf2 = new PARAFORMAT2();
pf2.cbSize = Marshal.SizeOf( pf2 );
pf2.dwMask = RtfEx.PFM_ALIGNMENT;
pf2.wAlignment = RtfEx.PFA_CENTER;
int rc = RtfEx.SendParaFmtMsg( rtfTextBox.Handle, RtfEx.EM_SETPARAFORMAT, 0, ref pf2 );
Jeśli natomiast chodzi o zapisanie tego w Delphi to myślę, że musisz skorzystać z metody StructureToPtr klasy Marshal. Nie wiem czy nie będzie też potrzebne przekopiowanie pamięci (metoda Copy).
Spróbowałem coś takiego:
procedure TForm2.RE_SetLineSpacing(ARichEdit: TRichEdit; lineSpacing: Byte);unsafe;
var
pf2: ParaFormat2;
Buffer : IntPtr;
begin
pf2.cbSize := SizeOf(PARAFORMAT2);
pf2.dwMask := PFM_LINESPACING;
pf2.bLineSpacingRule := lineSpacing;
Buffer := Marshal.AllocHGlobal(Marshal.SizeOf(pf2));
try
Marshal.StructureToPtr(TObject(pf2), Buffer, False);
SendMessage(ARichEdit.Handle, EM_SETPARAFORMAT, 0, Buffer.ToInt32);
finally
Marshal.DestroyStructure(Buffer, TypeOf(pf2));
end;
end;
Przez kompilator przechodzi ale nistety nie daje efektu (zmiana odtępu miedzy wierszami w RichEdit).
Może ktoś wie co źle napisałem [???] a może inaczej do tego trzeba się zabrać :-/
Spróbuj jeszcze dać Copy przed StructureToPtr
Marshal.Copy(pf2, 0, Buffer, Marshal.SizeOf(pf2));
AdamPL napisał(a)
Spróbuj jeszcze dać Copy przed StructureToPtr
Marshal.Copy(pf2, 0, Buffer, Marshal.SizeOf(pf2));
Dodałem i niestety : There is no overloaded version of 'Copy' that can be called with these arguments :-(