2011-07-19 8 views
8

मैं ओलेवीरिएंट में एन्सेप्लेटेड इंटरफ़ेस को रिलीज़ करने के लिए एक सुरक्षित/निर्धारिक तरीका खोजने का प्रयास कर रहा हूं।OleVariant के पीछे एक इंटरफ़ेस मुक्त करने का सही तरीका क्या है?

AFAICS डेल्फी एक प्रक्रिया के अंत में इंटरफेस संदर्भ जारी करता है, लेकिन मेरे मामले में मुझे इसे पहले करना है, क्योंकि मुझे COM को बंद करना है।

procedure Test; 
var 
    LLibrary: OleVariant; 
begin 
    CoInitialize(nil); 
    try 
    LLibrary := Null; 
    try 
     LLibrary := CreateOleObject(LibraryName); 
    finally 
     LLibrary := Unassigned; // <-- I would like to release the interface here 
    end; 
    finally 
    CoUninitialize; // <-- Shutdown of COM 
    end; 
end; // <-- The compiler releases the interface here 
मैं एक अतिरिक्त वर्ग उदाहरण इससे पहले कि मैं CoUninitialize फोन मैं रिक्त कर सकते हैं OleVariant डालने की हालांकि

procedure Test; 
var 
    Container: TLibraryContainer; // Holds the OleVariant 
begin 
    CoInitialize(nil); 
    try 
    Container := TLibraryContainer.Create; 
    try 
     {...} 
    finally 
     Container.Free; 
    end; 
    finally 
    CoUninitialize; 
    end; 
end; 

क्या यह समाधान सुरक्षित है या क्या कोई बेहतर समाधान है जिसे मैंने अनदेखा किया है?

उत्तर

9

कंपाइलर CreateOleObject से वापसी मूल्य के लिए स्पष्ट रूप से एक अंतर्निहित स्थानीय इंटरफ़ेस चर का उपयोग कर रहा है। यह तब आपके लिए बहुत देर हो चुकी है, दिनचर्या के अंत में जारी किया जाता है।

इसे हराने के कुछ तरीके हैं। सबसे पहले आप इंटरफ़ेस संदर्भ CreateOleObject द्वारा लौटाए गए इंटरफ़ेस संदर्भ के बारे में स्पष्ट हो सकते हैं। यह आपको अपने जीवनकाल को नियंत्रित करने की अनुमति देता है।

procedure Test; 
var 
    intf: IDispatch; 
    LLibrary: OleVariant; 
begin 
    CoInitialize(nil); 
    try 
    intf := CreateOleObject(LibraryName); 
    try 
     LLibrary := intf; 
    finally 
     VarClear(LLibrary); 
     intf := nil; 
    end; 
    finally 
    CoUninitialize; 
    end; 
end; 

एक वैकल्पिक कोड है कि अपने स्वयं के दायरे के साथ एक अलग दिनचर्या में CreateOleObject कहा जाता है ले जाने के लिए किया जाएगा।

procedure DoWork; 
var 
    LLibrary: OleVariant; 
begin 
    LLibrary := CreateOleObject(LibraryName); 
    //do stuff with LLibrary 
end; 

procedure Test; 
begin 
    CoInitialize(nil); 
    try 
    DoWork; 
    finally 
    CoUninitialize; 
    end; 
end; 

के बाद से अंतर्निहित स्थानीय संदर्भ DoWork के दायरे के भीतर है यह इसलिए इससे पहले कि आप CoUninitialize चलाने DoWork के अंत में जारी किया गया है और।

मेरी सिफारिश दूसरे विकल्प का उपयोग करना है जो क्लीनर है और संकलक को आपकी तरफ से काम करने के लिए मजबूर करता है।

+2

एकमात्र वास्तविक विकल्प द्वितीयक दिनचर्या का उपयोग कर रहा है, जब तक कि आप गिनती फ़ंक्शन कॉल का आनंद न लें और यह सुनिश्चित करने के लिए जेनरेट किए गए असेंबलर कोड का निरीक्षण न करें कि कोई छुपा स्थानीय चर नहीं है। अपने 'DoWork' दिनचर्या को कॉल करने के लिए +1 ... 'DoWork', विवरण के लिए मेरा हटाए गए उत्तर देखें। –

+0

@Cosmin मैं मानता हूं कि दूसरा विकल्प बेहतर है। –

+0

असल में मेरा असली कोड थोड़ा अधिक परिष्कृत है और मुझे लगता है कि मुझे आपके पहले संस्करण का उपयोग करना होगा, लेकिन मैं कोड को दोबारा करने की कोशिश करूंगा ताकि मैं दूसरे का उपयोग कर सकूं। :) –

संबंधित मुद्दे