2012-03-13 14 views
6

मुझे कॉलिंग inno सेटअप स्क्रिप्ट में एक स्ट्रिंग मान वापस करने की आवश्यकता है। समस्या यह है कि आवंटित स्मृति को प्रबंधित करने का कोई तरीका नहीं मिल रहा है। अगर मैं डीएलएल पक्ष पर आवंटित करता हूं, तो मेरे पास स्क्रिप्ट पक्ष पर विघटन करने के लिए कुछ भी नहीं है। मैं आउटपुट पैरामीटर का उपयोग नहीं कर सकता, क्योंकि पास्कल स्क्रिप्ट में कोई आवंटन फ़ंक्शन नहीं है। मुझे क्या करना चाहिए?एक डीएलएल से इनो सेटअप में स्ट्रिंग कैसे वापस करें?

उत्तर

7

यहाँ कैसे एक स्ट्रिंग है कि एक DLL से रिटर्न आवंटित करने के लिए का एक नमूना कोड है:

[code] 
Function GetClassNameA(hWnd: Integer; lpClassName: PChar; nMaxCount: Integer): Integer; 
External '[email protected] StdCall'; 

function GetClassName(hWnd: Integer): string; 
var 
    ClassName: String; 
    Ret: Integer; 
begin 
    // allocate enough memory (pascal script will deallocate the string) 
    SetLength(ClassName, 256); 
    // the DLL returns the number of characters copied to the buffer 
    Ret := GetClassNameA(hWnd, PChar(ClassName), 256); 
    // adjust new size 
    Result := Copy(ClassName, 1 , Ret); 
end; 
+0

क्या यह उत्तर आपको प्रश्न देता है? – kobik

+0

हां, खेद है कि मैं कुछ दिनों (और सप्ताहांत) के लिए काम से दूर था। स्वीकृत और धन्यवाद। –

2

ऐसा करने का एकमात्र व्यावहारिक तरीका इनो सेटअप में एक स्ट्रिंग आवंटित करना है, और उस पर एक सूचक को अपने डीएलएल की लंबाई के साथ पास करना है जो उसके बाद लौटने से पहले लंबाई मूल्य तक लिखता है।

यहां कुछ उदाहरण कोड taken from the newsgroup है।

function GetWindowsDirectoryA(Buffer: AnsiString; Size: Cardinal): Cardinal; 
external '[email protected] stdcall'; 
function GetWindowsDirectoryW(Buffer: String; Size: Cardinal): Cardinal; 
external '[email protected] stdcall'; 

function NextButtonClick(CurPage: Integer): Boolean; 
var 
    BufferA: AnsiString; 
    BufferW: String; 
begin 
    SetLength(BufferA, 256); 
    SetLength(BufferA, GetWindowsDirectoryA(BufferA, 256)); 
    MsgBox(BufferA, mbInformation, mb_Ok); 
    SetLength(BufferW, 256); 
    SetLength(BufferW, GetWindowsDirectoryW(BufferW, 256)); 
    MsgBox(BufferW, mbInformation, mb_Ok); 
end; 

अधिक अद्यतित चर्चा के लिए this thread भी देखें।

+0

मैं इसे कैसे Inno सेटअप में आवंटित करते हैं? –

+0

सेटलेथेंथ (स्ट्रवर, कुछ तरंगदैर्ध्य); –

+0

उत्तर एक उदाहरण के साथ अद्यतन किया गया है। – Deanna

2

एक बहुत ही सरल समाधान मामले के लिए जहां DLL समारोह केवल एक बार स्थापना में कहा जाता है - स्ट्रिंग के लिए अपने डीएल में एक वैश्विक बफर का उपयोग करें।

DLL पक्ष:

char g_myFuncResult[256]; 

extern "C" __declspec(dllexport) const char* MyFunc() 
{ 
    doSomeStuff(g_myFuncResult); // This part varies depending on myFunc's purpose 
    return g_myFuncResult; 
} 

Inno-सेटअप पक्ष:

function MyFunc: PChar; 
external '[email protected]:mydll.dll cdecl'; 
+1

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

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