मैं कर दिया है, एक से अधिक अवसर पर, लोगों को इंटरॉप प्रयोजनों के लिए प्रकार WideString
की वापसी मान का उपयोग करने की सलाह दी।इंटरऑप के लिए फ़ंक्शन रिटर्न वैल्यू के रूप में वाइडस्ट्रिंग का उपयोग क्यों नहीं किया जा सकता है?
- Accessing Delphi DLL throwing ocasional exception
- ASP.NET web app calling Delphi DLL on IIS webserver, locks up when returning PChar string
- Why can Delphi DLLs use WideString without using ShareMem?
विचार है कि एक WideString
एक BSTR
रूप में ही है। क्योंकि एक BSTR
साझा कॉम ढेर पर आवंटित किया जाता है तो यह एक अलग मॉड्यूल में एक मॉड्यूल और पुनःआवंटन में आवंटित करने के लिए कोई समस्या नहीं है। ऐसा इसलिए है क्योंकि सभी पार्टियां एक ही ढेर, COM ढेर का उपयोग करने के लिए सहमत हो गई हैं।
हालांकि, ऐसा लगता है कि WideString
इंटरॉप के लिए एक समारोह वापसी मान के रूप में नहीं किया जा सकता।
निम्नलिखित डेल्फी DLL पर विचार करें।
library WideStringTest;
uses
ActiveX;
function TestWideString: WideString; stdcall;
begin
Result := 'TestWideString';
end;
function TestBSTR: TBstr; stdcall;
begin
Result := SysAllocString('TestBSTR');
end;
procedure TestWideStringOutParam(out str: WideString); stdcall;
begin
str := 'TestWideStringOutParam';
end;
exports
TestWideString, TestBSTR, TestWideStringOutParam;
begin
end.
और निम्नलिखित सी ++ कोड:
typedef BSTR (__stdcall *Func)();
typedef void (__stdcall *OutParam)(BSTR &pstr);
HMODULE lib = LoadLibrary(DLLNAME);
Func TestWideString = (Func) GetProcAddress(lib, "TestWideString");
Func TestBSTR = (Func) GetProcAddress(lib, "TestBSTR");
OutParam TestWideStringOutParam = (OutParam) GetProcAddress(lib,
"TestWideStringOutParam");
BSTR str = TestBSTR();
wprintf(L"%s\n", str);
SysFreeString(str);
str = NULL;
TestWideStringOutParam(str);
wprintf(L"%s\n", str);
SysFreeString(str);
str = NULL;
str = TestWideString();//fails here
wprintf(L"%s\n", str);
SysFreeString(str);
TestWideString
करने के लिए कॉल इस त्रुटि के साथ विफल:
Unhandled exception at 0x772015de in BSTRtest.exe: 0xC0000005: Access violation reading location 0x00000000.
इसी प्रकार, यदि हम पी के साथ सी # से कॉल करने के लिए कोशिश/आह्वान , हमारे पास विफलता है:
[DllImport(@"path\to\my\dll")]
[return: MarshalAs(UnmanagedType.BStr)]
static extern string TestWideString();
त्रुटि है:
An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occurred in ConsoleApplication10.exe
Additional information: External component has thrown an exception.
कॉलिंग TestWideString
पी के माध्यम से/आह्वान काम करता है के रूप में उम्मीद।
तो, उपयोग पारित-दर-संदर्भ WideString मानकों के साथ और उन्हें मानचित्रण BSTR
पर पूरी तरह से अच्छी तरह से काम करने के लिए प्रकट होता है। लेकिन फ़ंक्शन रिटर्न मानों के लिए नहीं। मैंने डेल्फी 5, 2010 और एक्सई 2 पर इसका परीक्षण किया है और सभी संस्करणों पर एक ही व्यवहार का निरीक्षण किया है।
निष्पादन डेल्फी प्रवेश करती है और लगभग तुरंत विफल रहता है। Result
असाइनमेंट System._WStrAsg
के लिए एक कॉल में बदल जाता है, जो की पहली पंक्ति में लिखा है:
CMP [EAX],EDX
अब, EAX
$00000000
है और स्वाभाविक रूप से वहाँ एक पहुँच उल्लंघन है।
क्या कोई इसे समझा सकता है? क्या मुझसे कुछ गलत हो रही है? क्या मैं WideString
फ़ंक्शन मानों को BSTR
के व्यवहार्य होने की अपेक्षा करने में अनुचित हूं? या यह सिर्फ एक डेल्फी दोष है?
डेविड, हो सकता है कि 'सी जोड़ने ++', 'सी #' भी टैग? – kobik
@ कोबिक मेरा मानना है कि यह वास्तव में एक प्रश्न है कि डेल्फी वापसी मूल्यों को कैसे लागू करता है। मुझे लगता है कि डेल्फी अजीब है। –
@J ... मैंने कभी भी एक COM विधि नहीं देखी है जो 'HRESULT' वापस नहीं लौटा। हालांकि मैं COM में BSTR का उपयोग करने के बारे में बात नहीं कर रहा हूं। मैं इसके बारे में विभिन्न मॉड्यूल के बीच एक ढेर साझा करने के लिए एक सुविधाजनक तरीका के रूप में बात कर रहा हूँ। –