चेतावनी: हालांकि नीचे दिया गया उत्तर उस प्रश्न को संबोधित करता है जो पूछा गया था, मैं अनुशंसा करता हूं कि कोई भी इसका उपयोग कभी नहीं करेगा। यदि आप Round
से अलग-अलग गोल करना चाहते हैं तो एक समर्पित फ़ंक्शन लिखें और कॉल करें।
आप Round
के कार्यान्वयन को बदलने के लिए रनटाइम कोड हुक का उपयोग कर सकते हैं।
शिकन यह है कि Round
फ़ंक्शन के पते को पकड़ना थोड़ा मुश्किल है, हालांकि यह एक आंतरिक है। इस्तेमाल किए गए कॉलिंग सम्मेलन का पालन करने के लिए आपको सावधान रहना होगा। इनपुट मान x87 स्टैक रजिस्टर ST(0)
में पारित किया गया है और वापसी मान EDX:EAX
में 64 बिट पूर्णांक है।
यहां यह कैसे करें।
procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
OldProtect: DWORD;
begin
if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
Move(NewCode, Address^, Size);
FlushInstructionCache(GetCurrentProcess, Address, Size);
VirtualProtect(Address, Size, OldProtect, @OldProtect);
end;
end;
type
PInstruction = ^TInstruction;
TInstruction = packed record
Opcode: Byte;
Offset: Integer;
end;
procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
NewCode: TInstruction;
begin
NewCode.Opcode := $E9;//jump relative
NewCode.Offset :=
NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;
function System_Round: Pointer;
asm
MOV EAX, offset [email protected]
end;
procedure _ROUND;
asm
{ -> FST(0) Extended argument }
{ <- EDX:EAX Result }
// your implementation goes here
end;
initialization
RedirectProcedure(System_Round, @_ROUND);
आप बल्कि एएसएम से पास्कल में अपने संस्करण को लागू होता है तो आप मानक डेल्फी बुला सम्मेलन को _ROUND
की अमानक बुला सम्मेलन अनुकूल करने के लिए की जरूरत है। इस तरह:
function MyRound(x: Extended): Int64;
begin
// your implementation goes here
end;
procedure _ROUND;
var
x: Extended;
asm
{ -> FST(0) Extended argument }
{ <- EDX:EAX Result }
FSTP TBYTE PTR [x]
CALL MyRound
end;
ध्यान दें कि मैंने यहां माना है कि आपका प्रोग्राम 32 बिट को लक्षित कर रहा है। यदि आपको 64 बिट को लक्षित करने की आवश्यकता है तो सिद्धांत बहुत समान हैं, लेकिन विवरण स्पष्ट रूप से भिन्न हैं।
स्रोत
2013-06-07 08:38:31
System.round के व्यवहार वास्तव में सेट किया जा सकता http://docwiki.embarcadero.com/Libraries/XE2/en/System.Round के अनुसार। – RobS
आप प्रकाशित 'फ़ंक्शन राउंड (विस्तारित): विस्तारित' के साथ केवल नई इकाई बना सकते हैं, इस इकाई को अपनी प्रत्येक स्रोत फ़ाइलों के 'उपयोग' अनुभाग में शामिल करें और पुन: संकलित करें। यदि आपने पूरी तरह से योग्य नाम का उपयोग नहीं किया है (और लगभग कोई भी इसे सर्वव्यापी आरटीएल फ़ंक्शन के लिए नहीं करता है) तो ई-संकलन पर आपका नया फ़ंक्शन 'System.Round' से अधिक दिखाई देगा। वैश्विक व्यवहार को बदलने से आपके प्रोग्राम में कुछ तृतीय-पक्ष कोड के लिए अजीब परिणाम हो सकते हैं, –
सहमत - यह सबसे आसान तरीका है। +1 –