2011-12-06 122 views
1

我的應用程序與德爾福2010年編譯。該應用程序加載一個Delphi 7編譯的DLL加載一個Delphi 2010編譯的DLL。德爾福2010年應用程序加載一個德爾福7 DLL

D2010 app LOADS D7 DLL LOADS D2010 DLL 

的D7 DLL的導出函數使用Widestrings和德爾福2010 DLL使用strings的導出函數。我們都知道,Delphi 2010中的strings是Unicode(2字節),而在Delphi 7中它們是Ansi(1字節)。

我所有的測試都表明,儘管它不應該這樣,但它仍在工作。我想知道:

爲什麼它工作?

什麼可以出錯?

我應該使用哪種內存管理器(德爾福2010或Delphi 7的內存管理器DLL)

+0

這是一個錯誤,這是工作? ;-) – Pol

+0

@Pol no,它不是。我只是想明白它爲什麼起作用。 –

+0

對您的問題沒有影響,但您可以在兩側使用WideString。 – Pol

回答

7

在D2009和D2010,在RTL已制定邏輯(編譯器的{$STRINGCHECKS ON}指令),允許AnsiString接收Unicode的有效載荷,以及一個UnicodeString,用於在模塊邊界上接收Ansi有效負載,然後在訪問AnsiString/UnicodeString數據時執行無提示行內數據轉換爲正確的字符串類型。這主要是爲了支持傳統的C++項目,這些項目使用事件處理程序,在C++端使用AnsiString參數,在Delphi端使用UnicodeString變量。在這種情況下,它也可以允許D7 DLL將Ansi數據傳遞給D2010 DLL(雖然在XE中刪除了STRINGCHECKS指令)。

但是我期望D2010 DLL失敗,因爲在D2009中StrRec記錄(它在內存中的字符數據前面)的內存佈局發生了變化,以便添加對代碼頁的支持,所以D7 DLL不會分配D2010兼容StrRecAnsiString值傳遞給D2010 DLL中的UnicodeString參數。我期望D2010 DLL在嘗試訪問不存在的/空閒內存時崩潰。

這是另一個反對通過DLL邊界傳遞String類型的另一個論據。只是不要這樣做,永遠。改爲使用WideStringPAnsiChar/PWideChar

+0

+1作爲詳盡的答案。 – Pateman

+0

+1爲偉大的答案。 –

+0

+1很棒的答案。更多關於STRINGCHECKS的信息http://www.micro-isv.asia/2010/09/stringchecks-gone-in-delphi-xe/ – Pol