Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Ejecutable creado en Delphi 6 utiliza librería en Delphi Rio(dll) (https://www.clubdelphi.com/foros/showthread.php?t=93852)

Maniches 08-04-2019 23:32:41

Ejecutable creado en Delphi 6 utiliza librería en Delphi Rio(dll)
 
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:
Código Delphi [-]
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)
Código Delphi [-]
// 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

Código Delphi [-]


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

Código Delphi [-]


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;


La franja horaria es GMT +2. Ahora son las 12:29:59.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi