2016-08-01 61 views
0

我已經創建了一個包含一些函數的DLL文件,並希望在其不同的函數中多次重用程序。但是,當調用相同的DLL函數時,Access-violation錯誤出現在程序的第二個函數之後。動態調用並重用DLL函數

我目前使用的是GetProcAddress。例如:

function xyz:boolean 
var 
    dllHandle : cardinal; 
    EnBFStr : TEnBFStr; 
    StrToHex : TStrToHex; 
    Encodeddata , HexString : UnicodeString; 

    begin 
    dllHandle := LoadLibrary('Utilities.dll') ; 
    if dllHandle <> 0 then 
    begin 
     Encodeddata:='Sample'; 
     @EnBFStr := GetProcAddress(dllHandle, 'EncodeBlowFishString') ; 
     @StrToHex := GetProcAddress(dllHandle, 'UniStrToUniHexStr') ; 
     if Assigned (EnBFStr) then 
      Encodeddata:=EnBFStr('Key','Text') ; //Sample would be replaced 

     if Assigned (StrToHex) then 
      HexString :=StrToHex(Encodeddata) ; //call the function 

     FreeLibrary(dllHandle) ; 
end; 

還有其他函數正在加載庫並調用這些DLL函數多次。而且,在相同的過程/函數中,我們在(IF Else)條件下多次調用這些DLL函數。

在程序的前面部分,我試圖檢查DLL文件是否存在。此外,我試圖直接加載功能作爲另一種選擇:

function EncodeBlowFishString (Const Key:UnicodeString; Const DecodedString:UnicodeString;): UnicodeString; stdcall; 
external 'Utilities.dll' name 'EncodeBlowFishString'; 

function UniStrToUniHexStr(Const aString:UnicodeString): UnicodeString; stdcall; 
external 'Utilities.dll'; 

回答

3

你打破了DLL的內存分配規則。返回值由被調用者分配,但由調用者釋放。兩種解決方案:

  1. 使用ShareMem如在新庫項目頂部的註釋中所述。
  2. 使用標準的互操作技術來確保分配和釋放始終發生在同一模塊中。

順便說一句,每次要使用DLL時,加載和卸載DLL都是非常浪費的。只加載一次DLL。

此外,我想指出,加密對二進制數據進行操作,在我看來,你正在通過工作而不是文本來存儲一個痛苦的世界。

+0

你是對的。我正在使用二進制數據對其進行加密。這只是一個例子。 –

+0

您正在傳遞文本而不是二進制文件。 –

+0

對不起,其實,EncodeBlowFishString自定義函數本身爲我做的一切。這就是爲什麼,我通過了Unicode字符串,然後它將其中的所有內容都轉換成了。這是內聯,然後我決定有一個所有這些自定義函數的DLL –