将参数从Delphi 5传递到Delphi DLL XE

时间:2011-10-31 23:10:44

标签: delphi

我在应用程序代码中有一个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;

DYNAMIC CRASH 主要应用

  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;
  ;

这是正确的方法吗?

3 个答案:

答案 0 :(得分:3)

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

在这种情况下,您只需切换到使用以null结尾的字符串,即PAnsiChar。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

使用Delphi XE改变了ansistring的布局:现在在负偏移处还有一个代码页字段,D5没有。 EG:来自D5和DXE的字符串完全不兼容。因此,如果字符串可能包含#$ 00字节,则应在接口中使用PAnsiChar或PWideChar,以零终止(Delphi字符串始终为零终止)引入带有长度的额外参数。

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

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

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