PDA

Ver la Versión Completa : Ejecutable creado en Delphi 6 utiliza librería en Delphi Rio(dll)


Maniches
08-04-2019, 23:32:41
Buen Días a los amigos del foro,
Aquí después de unos días acudiendo a su experiencia y me ayuden a resolver un problema.

Proceso: Se quiere crear una DLL en Delphi 10 y que esta sea utilizada desde Delphi 6.
Nota: Cuando se define y crea ambos proyectos en D10 y usando la unidad “SimpleShareMem” para liberar la librería, no me da ningún problema usando todo como “string”, Si creo el App en D6 y que este utilice la DLL(D10) este genera un error de “Access Violation!!!”.

Yo he creado la DLL que devuelva tipo PCHAR por recomendación de unos foros y al ejecutar el App D6 ya no me muestra error, pero tan solo me devuelve un solo carácter de la cadena. Según el ejemplo tan solo devuelve: "P"

Me ayudan a detectar el problema en el App D6, La forma de como obtener la cadena completa desde el App D6?. ^\||/

Muchas Gracias.


Código de la DLL en D10:

library MyLibrary;
uses
System.SimpleShareMem,
System.SysUtils,
System.Classes;

function Test1(): PChar; stdcall;
begin
Result:= PChar('Prueba de Función en DLL');
end;

exports
Test1;


La APP en D6 y utiliza la DLL(Creada D10): (Contiene 2 formas de leer la DLL)

// PARA USO DE DLL EN BTN2
TTest1 = function() : PChar; stdcall;

implementation

// PARA USO DE DLL EN BTN1
function Test1() : PChar; stdcall; external 'MyLibrary.dll';

procedure TFormMain.btn1Click(Sender: TObject);
var
sResult : string;
begin
sResult:= string(Test1);
memo1.Lines.Clear;
memo1.Lines.Add(sResult);
end;

procedure TFormMain.btn2Click(Sender: TObject);
var
sResult: string;
Handle: THandle;
TestStr: TTest1;
begin
Handle := LoadLibrary('MyLibrary.dll');
if Handle <> 0 then
@TestStr:= GetProcAddress(Handle, 'RestAPIfJSON');
if @ TestStr <> nil then
begin
sResult := string(TestStr);
mmoJSONResult.Lines.Clear;
mmoJSONResult.Lines.Add(sResult);
end;
FreeLibrary(Handle);
end;
end;

Casimiro Notevi
09-04-2019, 00:02:38
Prueba a usar ansistring en lugar de string.

Maniches
09-04-2019, 00:14:12
Hola Casimiro.
Te refieres que haga la prueba usando AnsiString en donde? en la DLL (D10) o el APP (D6)? o en ambos?

Gracias por tus respuesta .

Casimiro Notevi
09-04-2019, 00:17:27
Es que los Delphi últimos usan unicode, por lo que delphi 6 no pueden usarlo.
Así que si en Delphi Río usas ansistring en lugar de string, lo podrás usar también en delhi 6.


Todo lo que sea string, cámbialo a ansistring. Casi seguro que ese es el problema.

Maniches
09-04-2019, 00:49:16
Casimiro,
Tenias mucha razón, hice el cambio de cambiar todo a AnsiString tanto el APP y la DLL. si bien es cierto ya me devuelve la cadena. pero sale el error "Invalid pointer operation."

en el primer caso en el método ADD y en el segundo en el método FreeLibrary.

que puede estar faltando?

Nota:
Cuando hice todo en D10 me salia error al hace click por segunda vez y ahí donde encontré que se debería de usar la unidad: "SimpleShareMem" y ya no me salio error. tendrá que ver algo similar en D6?

ElKurgan
10-04-2019, 09:02:52
No se si irán por ahí los tiros, pero también los PChar tienen soporte Unicode en los nuevos RAD Studio. En su lugar tendrías también que probar con PAnsiChar.

Saludos

Maniches
12-04-2019, 01:18:24
Gracias amigo Kurgan por tu respuesta.

He realizado el cambio que sugieres ("PAnsiChar") y me sale el mismo resultado según el ejemplo que adjunte. Me devuelve el carácter "P" como resultado.

Según la ayuda del buen amigo Casimiro el trabajar todo con AnsiString me devuelve la información. pero problema es al liberar la librería y el error que muestra es el indico en unos post anteriores.

Capaz alguien tenga una posible solucion? qP:-)

CrazySoft
19-04-2019, 14:12:48
Prueba de esta manera



con Rio 10.2




library MyLibrary;


uses
// System.SimpleShareMem, //no requiere
System.SysUtils,
System.Classes;

{$R *.res}
function Test1(): PAnsiChar; stdcall;
begin
Result:= PAnsiChar('Prueba de Función en DLL 1');
end;


exports
Test1,
Test2
;

begin
end.



con D7




unit Unit1;

interface

uses
// ShareMem, // no requiere, si se añade da error al cerrar la aplicacion
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

// PARA USO DE DLL EN BTN2
TTest1 = function() : PAnsiChar; stdcall;



var
Form1: TForm1;



implementation
// PARA USO DE DLL EN BTN1
function Test1() : PAnsiChar; stdcall; external 'MyLibrary.dll';



{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
sResult : AnsiString;
begin
sResult:=trim( Test1);
// memo1.Lines.Clear;
memo1.Lines.Add(sResult);
end;


procedure TForm1.Button2Click(Sender: TObject);

var
sResult: AnsiString;
Handle: THandle;
TestStr: TTest2;
begin
Handle := LoadLibrary('MyLibrary.dll');
if Handle <> 0 then
@TestStr:= GetProcAddress(Handle, 'Test1');
if @TestStr <> nil then
begin
sResult := TestStr;
// memo1.Lines.Clear;
memo1.Lines.Add(sResult);
end;
FreeLibrary(Handle);

end;