主要应用
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;
;
这是正确的方法吗?
答案 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