2016-08-01 60 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 –