【问题标题】:Passing parameters from Delphi 5 to Delphi DLL XE将参数从 Delphi 5 传递到 Delphi DLL XE
【发布时间】:2011-10-31 23:10:44
【问题描述】:

我有一个Delphi 5 应用程序,在应用程序代码中调用DLL 中的一个函数,传递整数和字符串参数,这在以静态方式调用DLL 时效果很好,当我尝试动态更改时不起作用。 传递参数以动态运行的正确方法是什么? 代码如下

主应用程序

  function Modulo_Pptos_Operacion(No_Orden : Integer; pathBD : string; PathBDConf :   String) : Integer ; stdcall;
 external 'LIB_Pptos_Oper.dll';

  Modulo_Pptos_Operacion(DmDatos.OrdenesNO_Orden.AsInteger,
   DmDatos.CiasPATHA.AsString, 'Alguna String');

DLL

  Modulo_Pptos_Operacion function (No_Orden: Integer; PathDB: AnsiString; PathDBConfig: AnsiString): Integer; StdCall;

动态崩溃 主要应用

  type
    TDLLPpto = function(No_Orden : Integer; PathDB : AnsiString; PathDBConfig : AnsiString) : Integer;
  var
    DLLHandle: THandle;
    : TDLLPpto;

  PROCEDURE CALL
    DLLHandle := LoadLibrary('LIB_Pptos_Oper.dll');
    DLLHandle <> 0 then
   begin
     @DLLPpto := GetProcAddress(DLLHandle, 'Modulo_Pptos_Operacion');
   end;
  ;

哪种方法是正确的?

【问题讨论】:

    标签: delphi


    【解决方案1】:

    问题可能是您混合了不同的运行时和可能不同的堆。 Delphi 字符串不是有效的互操作类型,因为它们的实现因版本而异。

    在这种情况下,您可以简单地切换到使用以 null 结尾的字符串 PAnsiChar。

    【讨论】:

    • 没错。 AnsiString 永远不会安全,即使您不混合使用 delphi 版本,除非主 EXE 和 DLL 都使用共享内存 (borlandmm.dll) 内存管理器。
    【解决方案2】:

    在动态加载 dll 的情况下,您在 TDLLPpto 的声明中省略了 stdcall; 调用约定指令。仍然建议使用PAnsiChar 类型跨可执行边界传递字符串。

    【讨论】:

    • 不仅是可取的,如果你不这样做,它通常会微妙地不稳定。为随机坏事做好准备。
    【解决方案3】:

    ansistring 的布局在 Delphi XE 中发生了变化:现在在负偏移处还有一个代码页字段,而 D5 没有。 EG:D5 和 DXE 的字符串完全不兼容。因此,您应该在界面中使用 PAnsiChar 或 PWideChar,如果字符串可能包含 #$00 个字节,则要么以零结尾(Delphi 字符串始终以零结尾),要么引入带有长度的额外参数。

    另外:不同的 Delphi 版本都有不同的内存管理器。如果一个字符串由主应用程序分配并由 DLL 释放(字符串被引用计数),则指针被传递给错误的内存管理器,这通常会导致内存损坏,从而导致严重的访问冲突等。

    另一种解决方案是使用 WideString;这在 D5 en DXE 中都等于 COM BSTR 字符串类型,并由操作系统而不是 Delphi 内存管理器管理。它们是兼​​容的。唯一的问题是:与 Delphi 字符串相比,它们速度较慢,并且不计算引用。

    总而言之:使用DLL接口时,尽量避免使用字符串,使用PAnsiChar或PWideChar,或WideString

    【讨论】:

    • WideString 也是一个很好的选择,我在回答中省略了它。我怀疑WideStringUnicodString/AnsiString 的性能在这里是否相关。
    • @David:我也对此表示怀疑,但其他人也会因为他们的问题而阅读这些答案,而且通常这类信息很重要 ;-)。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多