2010-02-21 7 views
5

निम्नलिखित कोड (केवल समस्या का प्रदर्शन करने के लिए निर्मित) डेल्फी 2010 में संकलित और काम करता है। डेल्फी 200 9 में, कंपाइलर "ई 2035 पर्याप्त वास्तविक पैरामीटर" में विफल रहता है।डेल्फी 200 9 में अज्ञात प्रक्रियाओं कास्टिंग

program Project50; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    TMyProc = reference to procedure(param: integer); 

var 
    a: TProc; 
    b: TMyProc; 

begin 
    b := procedure (param: integer) 
    begin 
    end; 
    a := TProc(b); // <-- [DCC Error] Project50.dpr(19): E2035 Not enough actual parameters 
end. 

मुझे समस्या के आसपास काम करने के लिए केवल एक बहुत बदसूरत हैक मिला है (ए: टीपीआरसी पूर्ण बी)। क्या इस कंपाइलर की कमी के लिए कोई भी अच्छे कामकाज के बारे में जानता है?

[टीपीआरसी क्षेत्र वास्तव में एक रिकॉर्ड के अंदर छिपा हुआ है जो विभिन्न 'निष्पादन योग्य' कोड - टीप्रोसेडर, टीएमआईडी और टीप्रोक स्टोर कर सकता है। कास्टिंग इस क्षेत्र में विशिष्ट गुमनाम proc स्टोर करने के लिए प्रयोग किया जाता है]

उत्तर

1

मैं एक हैक # 2 पाया है:।

program Project1; 

{$APPTYPE CONSOLE} 


uses 
    SysUtils; 

type 
    TMyProc = reference to procedure(param: integer); 

var 
    a: TProc; 
    b: TMyProc; 

begin 
    b := procedure (param: integer) 
    begin 
     Writeln('asdf'); 
    end; 
    PPointer(@a)^ := PPointer(@b)^; 
    a; 
    readln; 
end. 

मैं में संदेह है कि तुम क्या TMyProc बताए द्वारा प्राप्त करने के लिए कोशिश कर रहे हैं हूँ (परम तर्क के साथ) टीपीआरसी (तर्क के बिना)?


अपडेट किया गया: एक हैक # 3 (रेफरी काउंटर, विचार System._IntfCopy से चोरी हो जाता है को बढ़ा देते होना चाहिए):

procedure AnonCopy(var Dest; const Source); 
var 
    P: Pointer; 

begin 
    P:= Pointer(Dest); 
    if Pointer(Source) <> nil 
    then IInterface(Source)._AddRef; 
    Pointer(Dest):= Pointer(Source); 
    if P <> nil then 
    IInterface(P)._Release; 
end; 

var 
    a: TProc; 
    b: TMyProc; 

begin 
    b := procedure (param: integer) 
    begin 
     Writeln('asdf'); 
    end; 
    AnonCopy(a, b); 
// PPointer(@a)^ := PPointer(@b)^; 
    a; 
    readln; 
end. 
+0

यह परीक्षण मामले में काम करता है, लेकिन मेरे (थोड़ा अधिक जटिल) मामले में नहीं। वहाँ इंटरफेस संदर्भ गिनती के साथ कुछ गलत हो जाता है। मैं एक और सटीक परीक्षण मामले को एक साथ रखने की कोशिश करूंगा। टीपीआरसी अलग-अलग 'प्रक्रिया के संदर्भ' के लिए एक भंडारण क्षेत्र है, इसलिए मैं इसे कास्टिंग कर रहा हूं। शायद जेनेरिक के साथ कुछ अच्छा किया जा सकता है ... – gabr

+0

@gabr: मैंने हैक # 3 (इंटरफेस रेफ काउंटर बढ़ाना चाहिए) का प्रस्ताव देने के लिए अपनी पोस्ट अपडेट की है – kludg

+0

आपके सभी कामों के लिए धन्यवाद लेकिन मुझे अभी एक बहुत ही आसान तरीका मिला है इस समस्या को हल करें ... – gabr

2

चाल करने के लिए नहीं है

a := TProc(b); 

लेकिन

TMyProc(a) := b; 

जो डी 200 9 में संकलित और काम करता है। नीचे संलग्न नमूना परियोजना।

program Project51; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    TMyProc = reference to procedure(var param: integer); 

    TStorage = record 
    FDelegate: TProc; 
    end; 

var 
    a : TMyProc; 
    b : TMyProc; 
    param: integer; 
    stg : TStorage; 

begin 
    b := procedure (var param: integer) 
    begin 
     param := 2*param; 
    end; 
// stg.FDelegate := TMyProc(b); // doesn't compile in Delphi 2009, compiles in Delphi 2010 
    TMyProc(stg.FDelegate) := b; 
    param := 21; 
    TMyProc(stg.FDelegate)(param); 
    Writeln(param); 
    Readln; 
end. 

हालांकि, स्थानीय चर पर कास्टिंग करते समय यह काम नहीं करता है।

var 
    p: TProc; 
    a: TMyProc; 

TMyProc(p) := a; // this will not compile 

उत्सुकता और उत्सुकता।

1

ऐसा प्रतीत होता है कि रिकॉर्ड में सही प्रकार के प्रतिनिधि को स्टोर करने के लिए जेनेरिक का उपयोग करने का सबसे अच्छा तरीका होगा। कोई हैक आवश्यक है।

program Project51; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    TMyProc = reference to procedure(var param: integer); 

    TStorage<T> = record 
    FDelegate: T; 
    end; 

var 
    a : TMyProc; 
    b : TMyProc; 
    p : TProc; 
    param: integer; 
    stg : TStorage<TMyProc>; 

begin 
    b := procedure (var param: integer) 
    begin 
     param := 2*param; 
    end; 
    stg.FDelegate := b; 
    param := 21; 
    stg.FDelegate(param); 
    Writeln(param); 
    Readln; 
end.