PDA

Ver la Versión Completa : funcion en dll usada en vb6 se comporta diferente en delphi


erickperez6
26-05-2013, 17:53:50
Saludos,

Tengo una DLL que no se en que ambiente fue desarrollada, ni tampoco tengo documentacion de ella, solo tengo el codigo fuente de una aplicacion en visual basic 6 que la utiliza y funciona bien.

El problema lo tengo en una funcion que en vb6 funciona bien pero en delphi funciona pero a medias, me explico que sucede, tengo la siguiente declaracion de la funcion en vb6:

Private Declare Function AddMessageField Lib "efProtocol.dll" (ByVal szField As String, ByVal lFieldLength As Long) As Long

' dandole uso a la funcion
Private Sub AddField(sMessage As String)
Dim lAux As Long
lAux = AddMessageField(sMessage, Len(sMessage))
If lAux <> 0 Then ShowError (lAux)
End Sub

El procedimiento AddField lo que hace es mandar un mensaje al puerto serial y si la variable lAux trae un valor diferente a cero fue que ocurrio un error, resulta que es posible mandar mensajes en blanco en determinados momentos, es decir que puedo hacer esto:

AddField "" ' esto es valido

En la version para delphi funciona bien hasta que envio mensajes en blanco, siempre lAux me devuelve un numero diferente a cero, pero he hecho una copia fiel de vb6 a delphi. La definicion en delphi que hice es la siguiente:

type
tAddMessageField = function (szField : String; lFieldLength : Longint) : Longint; stdcall;

implementation

var
dllHandle : cardinal;
AddMessageField : tAddMessageField;

procedure cargardll;
begin
dllHandle := LoadLibrary('EFProtocol.dll') ;
if dllHandle <> 0 then
@SendSerialMessage := GetProcAddress(dllHandle, 'SendSerialMessage') ;
end;

function addcampo(texto : string) : longint;
begin
result := AddMessageField(texto, Length(texto));

// if result <> 0 then
// raise Exception.Create('hubo un error en un mensaje ' + IntToStr(result));
end;


No importa la situacion ni el momento, pero siempre que mando un mensaje en blanco obtengo un error en la version delphi, pero nunca en la vb6, creo que la definificion en delphi de la funcion no es la apropiada, a alguien le ha pasado algo similar?

nlsgarcia
26-05-2013, 21:12:34
erickperez6,


...Tengo una DLL...en vb6 funciona bien...siempre que mando un mensaje en blanco obtengo un error en la version delphi, pero nunca en la vb6...



' Declaración de la llamada a la DLL en VB6
Private Declare Function AddMessageField Lib "efProtocol.dll" (ByVal szField As String, ByVal lFieldLength As Long) As Long


Te comento:

1- En VB6 cuando una función envía un String por Valor a un DLL (ByVal), lo esta enviando como un String terminado en Nulo.

2- El tipo de dato Long en VB6 es equivalente a Integer en Delphi (Win32).

3- En el ejemplo en VB6 la función llamada en el DLL se denomina AddMessageField no SendSerialMessage, lo cual parece ser una incongruencia en el ejemplo en Delphi mostrado en el Msg #1.

Revisa este código:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TAddMessageField = function (szField : PChar; lFieldLength : Integer) : Integer; Stdcall;

var
Form1: TForm1;

implementation

{$R *.dfm}

var
dllHandle : Cardinal;
AddMessageField : TAddMessageField;

procedure CargarDll;
begin
dllHandle := LoadLibrary('EFProtocol.dll') ;
if dllHandle <> 0 then
@AddMessageField := GetProcAddress(dllHandle, 'AddMessageField')
else
MessageDlg('La Librería EFProtocol.dll No Fue Cargada',mtError,[mbYes],0);
end;

function AddCampo(Texto : String) : longint;
begin
if Assigned(AddMessageField) then
begin
if AddMessageField(PChar(Texto), Length(Texto)) <> 0 Then;
raise Exception.Create('Error en un Mensaje: ' + IntToStr(result));
end
else
MessageDlg('La Función AddMessageField No Fue Encontrada',mtError,[mbYes],0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
DataSerialPort : String;

begin

DataSerialPort := 'Texto a Enviar al Puerto Serial';

CargarDLL;

AddCampo(DataSerialPort);
AddCampo('');

FreeLibrary(dllHandle);

end;

end.

El código anterior carga una DLL de forma dinámica para el envío de datos a un puerto serial tomando en consideración los puntos señalados anteriormente en función del problema planteado.

Espero sea útil :)

Nelson.

erickperez6
29-05-2013, 18:37:53
si, tienes razon con la incogruencia, lo que pasa que tenia muchas funciones declaradas y las quite porque no venian al caso, y deje una funcion equivocada en el ejemplo.

En fin, resolvi el caso simplemente con definir el szField como Pchar y no como String.

TAddMessageField = function (szField : PChar; lFieldLength : Integer) : Integer; Stdcall;