Page 1 of 1

DLL32 funciones que regresan un valor entero

Posted: Sun Feb 05, 2012 2:35 am
by interwin
Buenas noches

Estoy implementando una llamada a una DLL desde un programa hecho con FWH y XHarbour.

El procedimiento para llamar a dicha DLL desde Delphi es

Code: Select all

.
.
.
type TError =
(
    OK,
    Arch_No_Encontrado,
    Dato_Obligatorio,
    Problemas_Certificado,
    Vigencia_Certificado,
    LlavePrivada,
    Version_CFD_Invalida,
    ErrorGeneral
);

function GeneraCFD(IniFileName, ClaveLlavePrivada : PChar) : TError; stdcall; external 'prueba.dll';

if GeneraCFD(PChar(OpenDialog.FileName),PChar(clave)) = OK then
.
.
.
.       
 
Yo la implemente de la siguiente manera:

Code: Select all

function Main()
   if .not. AbreDLL()
      msgAlert('La DLL para crear libreria CFDI no pudo ser abierta')
      resallfree()
      memory(-1)
      PostQuitMessage(0)
      __Quit()
      quit
   endIf

   A=GeneraCFD(cDirectorioPrograma+'\Tempo.ini', allTrim(Certs->PassKey) )

   msginfo(A)
return NIL

static Function AbreDLL()
   LOCAL lRet:=.F.
   LOCAL cDllName:="prueba.dll"

   hLibCFD:=LoadLibrary(cDllName)
   if Abs( hLibCFD ) <= 32
      MsgAlert( "Error code: " + LTrim( Str( hLibCFD ) ) + " loading " + cDllName )
      lRet:=.F.
   else
      lRet:=.T.
   endif
Return lRet

DLL32 FUNCTION GeneraCFD(cArchivoIni AS LPSTR, cPass AS LPSTR) AS LONG PASCAL FROM "prueba.dll" LIB hLibCFD
El problema es que GeneraCFD en lugar de regresarme un valor entre 0 y 8 me regresa el numero 35628288.

Ya probe con BYTE, _INT y con practimente todos los tipos de datos y siempre obtengo un resultado distinto del esperado.

¿Que estoy haciendo mal?.

¿De que forma puedo llamar esta DLL de forma lenguaje C.

Saludos

Re: DLL32 funciones que regresan un valor entero

Posted: Sun Feb 05, 2012 5:29 pm
by carlos vargas
la funcion el delphi retorna un dato tipo TError, hay que identificar si este es un tipo de dato tipo TObject, TRecord
o es un valor numerico.

salu2

Re: DLL32 funciones que regresan un valor entero

Posted: Sun Feb 05, 2012 5:56 pm
by interwin
Carlos

Gracias por responder. No se mucho de delphi (programe en pascal hace como 20 años) pero tengo entendido que al poner:

type TError =
(
OK,
Arch_No_Encontrado,
Dato_Obligatorio,
Problemas_Certificado,
Vigencia_Certificado,
LlavePrivada,
Version_CFD_Invalida,
ErrorGeneral
)

Se definen unas constantes con los siguientes valores

OK=0,Dato_Obligatorio=1,etc.

Por lo que la funcion GeneraCFD regresaria un valor entre 0 y 7, pero no se que me falta definir. Tal vez la solucion seria implementar en C en lugar de usar DLL32 pero no se como hacerlo.

Saludos.

Re: DLL32 funciones que regresan un valor entero

Posted: Mon Feb 06, 2012 12:52 am
by carlos vargas
sip, eso esta viendo que Terror era detipo trecord
ok, me parece que ya probaste con integer, long, prueba con UINT (short int) o CHAR que dependiendo del tamaño del numero puede ser usado como un tipo de dato numerico. ( int de 0 a 254 )
que si facilitas el dll seria mas facil probar. :-)

salu2

Re: DLL32 funciones que regresan un valor entero

Posted: Mon Feb 06, 2012 1:28 am
by Antonio Linares
Esta línea:

DLL32 FUNCTION GeneraCFD(cArchivoIni AS LPSTR, cPass AS LPSTR) AS LONG PASCAL FROM "prueba.dll" LIB hLibCFD

debería ser:

DLL32 FUNCTION GeneraCFD(cArchivoIni AS LPSTR, cPass AS LPSTR) AS LONG PASCAL FROM "GeneraCFD" LIB hLibCFD

Re: DLL32 funciones que regresan un valor entero

Posted: Mon Feb 06, 2012 5:49 am
by interwin
Buenas Noches

Antonio, Carlos Muchas Gracias por Responder.

En el ejemplo que puse en el foro me equivoque y puse FROM "prueba.dll" en lugar de FROM "GeneraCFD". Pero con las pruebas que he estado haciendo con mi programa si lo tenia correcto.

Por el momento solucione el problema de una forma no muy ortodoxa:

definiendo la funcion

DLL32 FUNCTION GeneraCFD(cArchivoIni AS LPSTR, cPass AS LPSTR) AS LONG PASCAL FROM "GeneraCFD" LIB hLibCFD

me di cuenta que cuando GeneraCFD deberia regresar 0 me regresaba el numero 35628288, 1 regresaba 35628289 y asi consecutivamente, por lo cual para obtener el valor correcto resto el numero 35628288 del valor obtenido por la funcion.

WnErrorGeneraCFD:=GeneraCFD(cDirectorioPrograma+'\Tempo.ini', allTrim(Certs->PassKey) )
WnErrorGeneraCFD:=WnErrorGeneraCFD-35628288

Pero debe de haber una forma de definir el tipo de dato que sea el correcto para obtener el valor adecuado, no supe como definir el tipo UINT en la funcion definida con DLL32

Carlos, por favor pasame tu mail para mandarte la lib.

Saludos

Re: DLL32 funciones que regresan un valor entero

Posted: Mon Feb 06, 2012 4:48 pm
by carlos vargas
donboscocorp2@hotmail.com

lo mas probable es que se necesite realizar wrapper en c para estas funciones.

salu2
carlos vargas

Re: DLL32 funciones que regresan un valor entero

Posted: Mon Feb 06, 2012 4:50 pm
by carlos vargas
http://www.validacfd.com/phpbb3/viewtop ... 58&start=0

aca hablan un poco del tema

Code: Select all

DLL32 FUNCTION GeneraCFD(cArchivoIni AS LPSTR, cPass AS LPSTR) AS BOOL PASCAL FROM "GeneraCFD" LIB "CFDLib.dll"
DLL32 FUNCTION GetError() AS STRING PASCAL FROM "GetError" LIB "CFDLib.dll"
DLL32 FUNCTION GetErrorExt() AS STRING PASCAL FROM "GetErrorExt" LIB "CFDLib.dll"
 
pero en este caso el valor retornado es boleano , y obtiene luego con las otras funciones ek numero del error

salu2
carlos vargas

Re: DLL32 funciones que regresan un valor entero

Posted: Tue Feb 07, 2012 5:28 pm
by interwin
Carlos.

Gracias por responder, de hecho yo puse ese post en la pagina del fabricante de la lib. En un principio hice mis pruebas usando bool pero tampoco obtengo el resultado obtenido. Parece ser que la funcion regresa la direccion de memoria donde se almacena el resultado de la funcion.

¿Como obtengo un valor a partir de una direccion de memoria?

Saludos.

Re: DLL32 funciones que regresan un valor entero

Posted: Tue Feb 07, 2012 10:09 pm
by Antonio Linares
Que tipo de valor es al que quieres acceder ? Un número, una cadena (texto) ?

http://dis.um.es/~lopezquesada/document ... 8/UT8I.pdf

Re: DLL32 funciones que regresan un valor entero

Posted: Tue Feb 07, 2012 10:16 pm
by Antonio Linares
Si devolviese una dirección a una cadena, podrias usar:

Code: Select all

HB_FUNC( STRFROMPTR )  // nDireccion --> cTexto
{
   hb_retc( ( char * ) hb_parnl( 1 ) );
}
 
Si devolviese la dirección de un número (LONG), podrias usar:

Code: Select all

HB_FUNC( NUMFROMPTR )  // nDirección --> nNumero
{
   hb_retnl( * ( HB_LONG * ) hb_parnl( 1 ) );
}