Page 1 of 1

Correct way to call an external DLL?

Posted: Wed Aug 27, 2014 1:02 pm
by Adolfo
Taken from the dll manual.

VARIANT_BOOL Conectar( [in] BSTR IPAdd, [in] long Portl)

Should I DO it like this ?

DLL FUNCTION Conectar( IPAdd AS LPSTR, Portl AS LONG ) AS BOOL PASCAL LIB "xxxxxx.dll"

Thisis my code...

PUBLIC hDLL := LoadLibrary("xxxxxx.dll")
lReturn:=Conectar("192.168.1.1",9999)

MsgInfo( lReturn )

FreeLibrary( hDLL )


But I get a nil value, instead of .T. or .F.

What am I doing wrong... any help will be appreciated

Thanks in advance.

From Chile
Adolfo

Re: Correct way to call an external DLL?

Posted: Wed Aug 27, 2014 6:29 pm
by Adolfo
UP...
Any idea?

Re: Correct way to call an external DLL?

Posted: Wed Aug 27, 2014 8:29 pm
by George
Hi Adolfo,

Code: Select all

DLL32 FUNCTION FTPGETFILE( hConnect AS LONG, cRemoteFile AS LPSTR, cNewFile AS LPSTR, nFailIfExists AS LONG, nFlagsAndAttribs AS DWORD, nFlags AS DWORD, @nContext AS PTR ) AS BOOL;
    PASCAL FROM "FtpGetFileA" LIB "wininet.dll"

DLL32 FUNCTION FTPPUTFILE( hConnect AS LONG, cLocalFile AS LPSTR, cNewRemoteFile AS LPSTR, nFlags AS DWORD, @nContext AS PTR ) AS BOOL;
    PASCAL FROM "FtpPutFileA" LIB "wininet.dll"
Regards,

George

Re: Correct way to call an external DLL?

Posted: Wed Aug 27, 2014 8:54 pm
by Adolfo
George.. thanks for answering.

I can load the DLL with no problem, no error, I can see the number of the Handle with no problem.

I tried to call the function in this way.

DLL32 FUNCTION Connect_NET( IPAdd AS STRING, Portl AS LONG ) AS BOOL PASCAL FROM "Connect_NET" LIB "zkemsdk.dll"

DLL32 FUNCTION Connect_NET( IPAdd AS STRING, Portl AS LONG ) AS BOOL FROM "Connect_NET" LIB "zkemsdk.dll"

DLL32 FUNCTION Connect_NET( IPAdd AS LPSTR, Portl AS LONG ) AS BOOL PASCAL LIB "zkemsdk.dll"

DLL32 FUNCTION Connect_NET( IPAdd AS LPSTR, Portl AS LONG ) AS BOOL LIB "zkemsdk.dll"



All of them with the same result NIL, no .T. or .F. as supposed
DLL manual says the function name and paramteres are:

VARIANT_BOOL Connect_NET( [in] BSTR IPAdd, [in] long Portl)
Return True if connected, otherwise False.... but I get a NIL

I'm out of ideas.

Re: Correct way to call an external DLL?

Posted: Wed Aug 27, 2014 11:42 pm
by Antonio Linares
Alfonso,

it is not the same a VARIANT_BOOL than a BOOL. There is no an automatic conversion from a VARIANT from the DLL call command, thats probably why you are geting nil as the return value

Re: Correct way to call an external DLL?

Posted: Wed Aug 27, 2014 11:58 pm
by Adolfo
Antonio... thanks...

So how am I supposed to retrieve it.. as what ?

Thanks

Re: Correct way to call an external DLL?

Posted: Thu Aug 28, 2014 12:12 am
by Antonio Linares
Probably as a pointer to the variant (just a generic pointer)

But once you get such pointer, you need to properly inspect it. Harbour has some functions for OLE management that you may try to adapt.

Re: Correct way to call an external DLL?

Posted: Thu Aug 28, 2014 12:29 am
by Adolfo
Ok
reading some info about it.. I discovered that

VARIANT_BOOL has 2 possible values

VARIANT_FALSE = 0
VARIANT_TRUE = -1

So maybe the function returns 0 or -1
DLL32 has no "Unknown" return value to declare, Because that way I could inspect it, or not.

Re: Correct way to call an external DLL?

Posted: Thu Aug 28, 2014 7:39 am
by Antonio Linares
Adolfo,

Te hablo en español y abreviamos :-)

Estoy revisando tu código y veo que se usa BSTR y eso no es un LPSTR. He buscado en el código de Harbour y efectivamente es una cadena "wide".

En Harbour\contrib\hbwin\olecore.c encuentras este código:

Code: Select all

static BSTR hb_oleItemToString( PHB_ITEM pItem )
{
   UINT uiStrLen = ( UINT ) hb_itemCopyStrU16( pItem, HB_CDP_ENDIAN_NATIVE,
                                               NULL, UINT_MAX );
   BSTR strVal = SysAllocStringLen( NULL, uiStrLen );

   hb_itemCopyStrU16( pItem, HB_CDP_ENDIAN_NATIVE, strVal, uiStrLen + 1 );

   return strVal;
}
que basicamente convierte un item de Harbour (tipo cadena) a una cadena wide BSTR (que son las usadas en OLE).

Asi que lo primero de todo es convertir tu cadena en BSTR y luego proporcionarla a tu función.

Re: Correct way to call an external DLL?

Posted: Thu Aug 28, 2014 7:46 am
by Antonio Linares
Despues de revisarlo no estoy tan seguro de que sea eso lo que necesitas, pues esa función convierte de un item de OLE a cadena y no de un item de Harbour.

Aqui esta todo el código de olecore.c para revisarlo pues se usan BSTR en otras partes más y asi ver cual es la forma correcta de hacer la conversión:

https://github.com/harbour/core/blob/ma ... /olecore.c

Re: Correct way to call an external DLL?

Posted: Thu Aug 28, 2014 11:01 pm
by Adolfo
Antonio...

Mirando algunas soluciones para mi problema, encontre esto




std::string ConvertWCSToMBS(const wchar_t* pstr, long wslen)
{
int len = ::WideCharToMultiByte(CP_ACP, 0, pstr, wslen, NULL, 0, NULL, NULL);

std::string dblstr(len, '\0');
len = ::WideCharToMultiByte(CP_ACP, 0 /* no flags */,
pstr, wslen /* not necessary NULL-terminated */,
&dblstr[0], len,
NULL, NULL /* no default char */);

return dblstr;
}

Y aqui de BSTR a STR, posibles 3
//----------------------
#include <comdef.h>

std::string myString = _bstr_t (myBSTR);



//----------------
void f(BSTR ms_str)
{
std::wstring ws(ms_str);
}

//*---------------

BSTR ConvertMBSToBSTR(const std::string& str)
{
int wslen = ::MultiByteToWideChar(CP_ACP, 0 /* no flags */,
str.data(), str.length(),
NULL, 0);

BSTR wsdata = ::SysAllocStringLen(NULL, wslen);
::MultiByteToWideChar(CP_ACP, 0 /* no flags */,
str.data(), str.length(),
wsdata, wslen);
return wsdata;
}

Que me dices.. no soy experto en C, pero este problema me tiene acogotado.

Saludos..

De ahi busco las opciones de recibir bien el VARIANT_BOOL

Re: Correct way to call an external DLL?

Posted: Fri Aug 29, 2014 4:13 pm
by Antonio Linares
Adolfo,

Si la IP fuese 192.168.1.1 proporcionasela asi: Chr( 0 ) + "1" + Chr( 0 ) + "9" + Chr( 0 ) + "2" + Chr( 0 ) + "." + ...

Re: Correct way to call an external DLL?

Posted: Fri Aug 29, 2014 6:40 pm
by Adolfo
Gracias Master...
Pruebo y comento...