elmago00,
Revisa esta información:
Cita:
In general, functions in a DLL can use any type of parameter and return any type of value. There are two exceptions to this rule:- If you plan to call the DLL from other programming languages, you should try using Windows native data types instead of Delphi-specific types. For example, to express color values, you should use integers or the Windows ColorRef type instead of the Delphi native TColor type, doing the appropriate conversions (as in the FormDLL example, described in the next section). For compatibility, you should avoid using some other Delphi types, including objects (which cannot be used by other languages) and Delphi strings (which can be replaced by PChar strings). In other words, every Windows development environment must support the basic types of the API, and if you stick to them, your DLL will be usable with other development environments. Also, Delphi file variables (text files and binary file of record) should not be passed out of DLLs, but you can use Win32 file handles.
- Even if you plan to use the DLL only from a Delphi application, you cannot pass Delphi strings (and dynamic arrays) across the DLL boundary without taking some precautions. This is the case because of the way Delphi manages strings in memory—allocating, reallocating, and freeing them automatically. The solution to the problem is to include the ShareMem system unit both in the DLL and in the program using it. This unit must be included as the first unit of each of the projects. Moreover, you have to deploy the BorlndMM.DLL file (the name stands for Borland Memory Manager) along with the program and the specific library.
Tomado del link : http://etutorials.org/Programming/ma...DLL+in+Delphi/
|
En el ejemplo del DLL propuesto en el
Msg #3,
No se siguieron las reglas descritas anteriormente dado que funciono correctamente en Delphi 2010 y Delphi XE4 (Asumo que también funcionaría en Delphi XE3), sin embargo en
Delphi 7 los ejemplos descritos
no funcionan correctamente, dado que en esta versión las reglas mencionadas son válidas.
En lo personal independientemente de la versión de Delphi que se utilice
siempre es preferible seguir las reglas anteriores por compatibilidad con otros lenguajes en Windows, pero si el DLL y el programa son ambos programados en
Delphi 2010 o
Delphi XE4 (Solo menciono estas versiones por que son las que he probado en el ejemplo, pero lo más probable es que se cumpla de Delphi 2010 a Delphi XE5),
es posible hacer el desarrollo del DLL y su programa asociado como se sugiere en el mensaje anterior en lo relacionado al uso de arreglos y strings como parámetros de un DLL.
Para evitar usar como parámetros
Arreglos y Strings en Delphi DLLs, estos pueden ser sustituidos por medio de
tipos PChar que permitan un medio confiable de intercambio de información entre diferentes lenguajes bajo Windows.
Revisa este código:
Código Delphi
[-]
library TestDLL2;
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
{$R *.res}
function GetArraySim(Value : PChar) : PChar; stdcall;
var
i : Integer;
AuxStr : String;
StrList : TStringList;
begin
StrList := TStringList.Create;
if (Value = 'Integer') then
begin
Randomize;
for i := 0 to 9 do
begin
AuxStr := IntToStr(Random(1000));
StrList.Add(AuxStr);
end;
Result := PChar(StrList.CommaText);
end;
if (Value = 'Double') then
begin
Randomize;
for i := 0 to 9 do
begin
AuxStr := FormatFloat('##0.00',(Random(100)+Random));
StrList.Add(AuxStr);
end;
Result :=PChar(StrList.CommaText);
end;
if (Value = 'String') then
begin
Randomize;
for i := 0 to 9 do
begin
AuxStr := 'String-' + IntToStr(Random(1000));
StrList.Add(AuxStr);
end;
Result :=PChar(StrList.CommaText);
end;
if (Value <> 'Integer') and (Value <> 'Double') and (Value <> 'String') then
begin
MessageDlg('Error en String de Selección',mtInformation,[mbOK],0);
Result := PChar(EmptyStr);
end;
StrList.Free;
end;
exports
GetArraySim;
begin
end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32,
implementa un DLL que recibe un Pchar de entrada y devuelve un Pchar de salida que contiene varios items de tipo Integer, Double y String delimitados por coma, la idea es simular un arreglo de salida por medio de datos de tipo TStrinList y Pchar.
Revisa este código
Código Delphi
[-]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
ComboBox1: TComboBox;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;
function SimulaArray(Value : PChar) : PChar; stdcall; external 'TestDLL2.dll' name 'GetArraySim';
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Items.Add('Integer');
ComboBox1.Items.Add('Double');
ComboBox1.Items.Add('String');
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ArrInt : Array of Integer;
ArrDbl : Array of Double;
ArrStr : Array of String;
i : Integer;
Msg : String;
StrList : TStringList;
begin
Memo1.Clear;
StrList := TStringList.Create;
if ComboBox1.Text = 'Integer' then
begin
StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
SetLength(ArrInt,StrList.Count);
for i := 0 to StrList.Count-1 do
begin
ArrInt[i] := StrToInt(StrList.Strings[i]);
Memo1.Lines.Add(IntToStr(ArrInt[i]));
end;
end;
if ComboBox1.Text = 'Double' then
begin
StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
SetLength(ArrDbl,StrList.Count);
for i := 0 to StrList.Count-1 do
begin
ArrDbl[i] := StrToFloat(StrList.Strings[i]);
Memo1.Lines.Add(FloatToStr(ArrDbl[i]));
end;
end;
if ComboBox1.Text = 'String' then
begin
StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
SetLength(ArrStr,StrList.Count);
for i := 0 to StrList.Count-1 do
begin
ArrStr[i] := StrList.Strings[i];
Memo1.Lines.Add(ArrStr[i]);
end;
end;
StrList.Free;
end;
end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32,
implementa el DLL (TestDLL2) que simula el arreglo de salida indicado anteriormente.
De esta forma
se pueden pasar gran cantidad de datos hacia y desde el DLL por medio de datos de tipo TStrinList y Pchar, otra forma es por medio de
Estructuras Tipo Record por Referencia, pero solo en los casos que amerite este tipo de datos.
Espero sea útil
Nelson.