2013-07-30 4 views
8

मेरे पास मेरे डीएलएल के अंदर एक कक्षा है। और यह डीएलएल इस वर्ग की वस्तुओं को बनाने और उनके तरीकों को कॉल करने के लिए एक "इंटरफ़ेस" प्रदान करता है।बहुभाषी अनुप्रयोग में डीएलएल और कक्षा

कक्षा कोड (सरलीकृत):

TLogger = class 
    private 
    // 
    public 
    function AddToLog(sBuf: PWideChar): Word; 
    constructor Create(Name: PWideChar); 
    destructor Destroy; override; 
end; 

constructor Create(Name: PWideChar); 
begin 
    // 
end; 

destructor TLogger.Destroy; 
begin 
    // 
end; 

function TLogger.AddToLog(sBuf: PWideChar): Word; 
var 
    Temp1 : WideString; 
    Temp2 : AnsiString; 

begin 
    Result := NO_ERRORS; 

    WaitForSingleObject(FMutex, INFINITE); 

    Temp1 := 'a'; 
    Temp2 := Temp1; 

    // 

    ReleaseMutex(FMutex); 
end; 

DLL कोड

function CreateLogger(LogFileName: PWideChar; PLogger: PCardinal): Word; stdcall; 
begin 
    try 
    PLogger^ := Cardinal(TLogger.Create(LogFileName)); 
    Result := NO_ERRORS; 
    except 
    Result := ERR_CREATE_OBJECT; 
    end; 
end; 

function DestroyLogger(PLogger: Cardinal): Word; stdcall; 
begin 
    try 
    TLogger(PLogger).Free; 
    Result := NO_ERRORS; 
    except 
    Result := ERR_OBJECT_NOT_FOUND; 
    end; 
end; 

function AddToLog(PLogger: Cardinal; BufStr: PWideChar): Word; stdcall; 
begin 
    try 
    Result := TLogger(PLogger).AddToLog(BufStr); 
    except 
    Result := ERR_OBJECT_NOT_FOUND; 
    end; 
end; 

जब मैं 1 धागे से इस लाइब्रेरी का उपयोग करने की कोशिश कर रहा हूँ - सब कुछ ठीक है। समस्याएं तब शुरू होती हैं जब मैं कई धागे बनाते हैं जो यादृच्छिक अवधि के साथ AddToLog को कॉल करते हैं (प्रत्येक थ्रेड में कक्षा का स्वयं का ऑब्जेक्ट होता है)। कुछ समय में मैं Access Violation या Invalid pointer operation पकड़ता हूं। मैंने कुछ शोध किया है और बताया है कि यदि परिवर्तनीय Temp2 में WideString प्रकार सब कुछ ठीक है। एक अन्य समाधान (यह सिर्फ एक "अनुसंधान" कोड है) पुस्तकालय कोड को म्युटेक्स स्थानांतरित करने के लिए है:

function AddToLog(PLogger: Cardinal; BufStr: PWideChar): Word; stdcall; 
begin 
    WaitForSingleObject(TLogger(PLogger).FMutex, INFINITE); 
    Result := TLogger(PLogger).AddToLog(BufStr); 
    ReleaseMutex(TLogger(PLogger).FMutex); 
end; 

दूसरा समाधान मेरे लिए विचार कर रहा है कि दो वस्तुओं से काम करना चाहिए क्योंकि प्रत्येक वस्तु अपने आप म्युटेक्स (है बुरा है एक फ़ाइल के साथ, उनके पास एक-दूसरे का इंतजार करने के लिए एक ही म्यूटेक्स होता है; यदि दो ऑब्जेक्ट्स को अलग-अलग फाइलों के साथ काम करना चाहिए, तो उनके पास अलग-अलग म्यूटेक्स हैं और समानांतर में काम करते हैं)।

मैं इस समस्या को 2 दिनों के लिए हल करने की कोशिश कर रहा हूं लेकिन मुझे समझ में नहीं आता कि क्या गलत है। स्ट्रिंग कास्ट इस तरह की समस्या का कारण बन सकता है? अपने DLL परियोजना के मुख्य कोड ब्लॉक में पहली पंक्ति के रूप

IsMultiThread := True; 

:

+0

ऐसा लगता है कि आपने बहुत अधिक कोड हटा दिया है। आपके पास यहां मौजूद कोड थ्रेडसेफ है, भले ही आप म्यूटेक्स को हटा दें, और भले ही सभी थ्रेड्स ने लॉगर का एक ही उदाहरण साझा किया हो। आपको एक एसएससीसीई की आवश्यकता है। –

+5

क्या आप ['IsMultiThread'] सेट करते हैं (http://docwiki.embarcadero.com/Libraries/XE4/en/System.IsMultiThread): = True; डीएलएल में? –

+0

@TOndrej आह, मुझे यकीन है कि यह है। 'IsMultiTread 'के साथ' गलत 'के रूप में ढेर आवंटक थ्रेडसेफ नहीं होगा। मेरा सुझाव है कि आप इसे एक उत्तर के रूप में जोड़ें। –

उत्तर

14

निम्न पंक्ति रखो। यह मेमोरी मैनेजर को थ्रेड-सुरक्षित मोड पर स्विच करने का निर्देश देगा। क्योंकि AnsiString डेल्फी स्मृति प्रबंधक द्वारा आवंटित किया जाता है, और WideString कॉम ढेर पर आवंटित किया जाता है

यह AnsiString और WideString जो व्यवहार अंतर समझा जाएगा। जब IsMultiThreadFalse है, डेल्फी मेमोरी मैनेजर थ्रेड-सुरक्षित नहीं है, लेकिन COM ढेर हमेशा थ्रेड-सुरक्षित है।

+0

+1 नोट यह भी कि वाइडस्ट्रिंग थ्रेड सुरक्षित है लेकिन AnsiString या यूनिकोडस्ट्रिंग से भी धीमी है। भले ही बीएसटी सिस्टम आवंटक गति ने XP Vista के बाद, Windows Vista के बाद बहुत कुछ बढ़ाया है। –

+0

इससे मुझे एक समस्या को हल करने में मदद मिली जो मैं 3 दिनों से संघर्ष कर रहा हूं। मैं COM ऑब्जेक्ट्स का उपयोग कर रहा हूं जो अलग-अलग थ्रेड से मेरी कॉलबैक कॉल कर सकते हैं। मैं सरणी (डी) आवंटन, इंटरफ़ेस मुक्त करने और रहस्यमय दौड़ की स्थिति के कारण कोड के चारों ओर गलत संदर्भ गिनती से संबंधित अजीब त्रुटियों का पीछा कर रहा हूं ... मैंने वास्तव में किया यह नहीं पता कि डिफ़ॉल्ट डेल्फी मेमोरी मैनेजर थ्रेड-सुरक्षित नहीं है जब तक कि आप इसे सक्षम न करें। –

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