Delphi 动态调用和重用DLL函数

Delphi 动态调用和重用DLL函数,delphi,dll,Delphi,Dll,我已经创建了一个带有一些函数的DLL文件,并希望在一个程序中多次在其不同的函数中重用。但是当调用相同的DLL函数时,访问冲突错误出现在程序的第二个函数之后 我目前正在使用GetProcAddress。例如: function xyz:boolean var dllHandle : cardinal; EnBFStr : TEnBFStr; StrToHex : TStrToHex; Encodeddata , HexString : UnicodeString;

我已经创建了一个带有一些函数的DLL文件,并希望在一个程序中多次在其不同的函数中重用。但是当调用相同的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的内存分配规则。返回值由被调用方分配,但由调用方解除分配。两种解决方案:

  • 使用新库项目顶部的注释中所述的
    ShareMem
  • 使用标准互操作性技术确保分配和解除分配始终发生在同一模块中 顺便说一句,每次使用DLL时加载和卸载它是非常浪费的。只加载DLL一次


    此外,我想指出的是,加密是在二进制数据上进行的,在我看来,你通过使用文本来存储痛苦的世界

    您正在打破DLL的内存分配规则。返回值由被调用方分配,但由调用方解除分配。两种解决方案:

  • 使用新库项目顶部的注释中所述的
    ShareMem
  • 使用标准互操作性技术确保分配和解除分配始终发生在同一模块中 顺便说一句,每次使用DLL时加载和卸载它是非常浪费的。只加载DLL一次


    此外,我想指出的是,加密是在二进制数据上进行的,在我看来,你通过使用文本来存储痛苦的世界

    你说得对。我用二进制数据加密它。这只是一个例子。您传递的是文本而不是二进制。对不起,实际上,EncodeBlowFishString自定义函数本身为我做了一切。这就是为什么,我传递了Unicode字符串,然后它将其中的所有内容都进行了转换。它是内联的,然后我决定为所有这些自定义函数设置一个DLL,这在我看来是个问题。您已失去对文本编码的控制。如果是我,我会明确指定一个编码。无论如何,这是一个旁白。我已经回答了您的实际问题。@david heffeman我在DLL中添加了一个包装器,这样它就可以完成大部分工作,而不是在任何调用程序或函数的范围之外重用相同的函数。我在stackoverflow中引用了你的例子。因为我是从帕斯卡·拉扎勒斯来到德尔菲的,有些事情更棘手。谢谢你的帮助。你说得对。我用二进制数据加密它。这只是一个例子。您传递的是文本而不是二进制。对不起,实际上,EncodeBlowFishString自定义函数本身为我做了一切。这就是为什么,我传递了Unicode字符串,然后它将其中的所有内容都进行了转换。它是内联的,然后我决定为所有这些自定义函数设置一个DLL,这在我看来是个问题。您已失去对文本编码的控制。如果是我,我会明确指定一个编码。无论如何,这是一个旁白。我已经回答了您的实际问题。@david heffeman我在DLL中添加了一个包装器,这样它就可以完成大部分工作,而不是在任何调用程序或函数的范围之外重用相同的函数。我在stackoverflow中引用了你的例子。因为我是从帕斯卡·拉扎勒斯来到德尔菲的,有些事情更棘手。谢谢你的帮助
    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';