Page 1 of 1
xHarbour Commercial and latest FWH
Posted: Sat Aug 05, 2023 2:06 am
by Randal
I recently upgraded to the latest FWH and I am able to compile my program using xBuilder/xHarbour however, I'm getting an error in a particular function.
I'm using a 3rd party lib for emailing. This is the code in question:
hSmtp := LoadLibrary("CSMTPAV9.dll")
// Must initialize first. Should return true
lSmtpInit := SmtpInitialize(CSTOOLS9_LICENSE_KEY)
DLL FUNCTION SmtpInitialize(license AS LPSTR, initdata AS LPSTR) AS BOOL ;
PASCAL FROM "SmtpInitializeA" LIB hSmtp
The license key is a define for a long string of random letters.
The error I get is:
Compiler version: xHarbour 1.2.3 Intl. (SimpLex) (Build 20170127)
FiveWin version: FWH 23.04
C compiler version: Pelles ISO C Compiler 3.0 (32-bit)
Windows 10 32 Bits, version: 6.2, Build 9200
Time from start: 0 hours 0 mins 23 secs
Error occurred at: 08/04/23, 20:52:10
Error description: Error BASE/1099 Argument error: STR
Args:
[ 1] = P 0x51000000
[ 2] = U
[ 3] = U
Stack Calls
===========
Called from: => STR( 0 )
Called from: Catalyst.Prg => SMTPINITIALIZE( 0 )
Called from: Catalyst.Prg => INITIALIZECATALYST( 230 )
Called from: Catalyst.Prg => LOADCATALYST( 204 )
Called from: Catalyst.Prg => (b)LOADCATLIBS( 192 )
Has something changed about the DLL FUNCTION? Should I be defining and calling this function another way? This has worked for years in previous versions of FWH and xHarbour.
Thanks,
Randal Ferguson
Re: xHarbour Commercial and latest FWH
Posted: Sat Aug 05, 2023 3:02 pm
by Antonio Linares
Dear Randal,
Your dll.ch must contain this:
Code: Select all | Expand
if ValType( _hDLL ) == "P" ;;
_pOld = _hDLL ;;
_hDLL = PtrToNum( _hDLL ) ;;
end ;;
Please double check that you are using the most recent dll.ch, here it is
Code: Select all | Expand
// Copyright FiveTech 1993-2022
#ifndef _DLL_CH
#define _DLL_CH
#ifndef _C_TYPES
#define _C_TYPES
#define VOID 0
#define BYTE 1
#define CHAR 2
#define WORD 3
#ifdef __CLIPPER__
#define _INT 4 // conflicts with Clipper Int()
#else
#define _INT 7
#endif
#define BOOL 5
#define HDC 6
#define LONG 7
#define STRING 8
#define LPSTR 9
#define PTR 10
#define _DOUBLE 11 // conflicts with BORDER DOUBLE
#define DWORD 12
#define LONGLONG 13
#endif
#translate NOREF([@]<x>) => <x>
#ifndef __HARBOUR__
#ifndef __XPP__
#ifndef __CLIPPER__
#ifndef __C3__
#define __CLIPPER__
#endif
#endif
#endif
#endif
#ifndef __CLIPPER__
#translate DLL32 => DLL
#endif
//----------------------------------------------------------------------------//
#xcommand DLL [<static:STATIC>] FUNCTION <FuncName>( [ <uParam1> AS <type1> ] ;
[, <uParamN> AS <typeN> ] ) ;
AS <return> [<pascal:PASCAL>] [ FROM <SymName> ] LIB <*DllName*> ;
=> ;
[<static>] function <FuncName>( [NOREF(<uParam1>)] [,NOREF(<uParamN>)] ) ;;
local _hDLL := If( ValType( <DllName> ) == "N", <DllName>, LoadLibrary( <(DllName)> ) ) ;;
local uResult ;;
local cFarProc ;;
local _pOld ;;
if ValType( _hDLL ) == "P" ;;
_pOld = _hDLL ;;
_hDLL = PtrToNum( _hDLL ) ;;
end ;;
if Abs( _hDLL ) > 32 ;;
cFarProc = GetProcAdd( _hDLL,;
If( [ Empty( <SymName> ) == ] .t., <(FuncName)>, <SymName> ),;
[<.pascal.>], <return> [,<type1>] [,<typeN>] ) ;;
uResult = FWCallDLL( cFarProc [,<uParam1>] [,<uParamN>] ) ;;
if ! Empty( _pOld ) ;;
_hDLL = _pOld ;;
end ;;
If( ValType( <DllName> ) == "N",, FreeLibrary( _hDLL ) ) ;;
else ;;
MsgAlert( "Error code: " + LTrim( Str( _hDLL ) ) + " loading " + ;
If( ValType( <DllName> ) == "C", <DllName>, Str( <DllName> ) ) ) ;;
end ;;
return uResult
//----------------------------------------------------------------------------//
#xcommand DLL32 [<static:STATIC>] FUNCTION <FuncName>( [ <uParam1> AS <type1> ] ;
[, <uParamN> AS <typeN> ] ) ;
AS <return> [<pascal:PASCAL>] [ FROM <SymName> ] LIB <*DllName*> ;
=> ;
[<static>] function <FuncName>( [NOREF(<uParam1>)] [,NOREF(<uParamN>)] ) ;;
local _hDLL := If( ValType( <DllName> ) == "N", <DllName>, LoadLib32( <(DllName)> ) ) ;;
local uResult ;;
local cFarProc ;;
local _pOld ;;
if ValType( _hDLL ) == "P" ;;
_pOld = _hDLL ;;
_hDLL = PtrToNum( _hDLL ) ;;
end ;;
if Abs( _hDLL ) > 32 ;;
cFarProc = GetProcAdd32( _hDLL,;
If( [ Empty( <SymName> ) == ] .t., <(FuncName)>, <SymName> ),;
[<.pascal.>], <return> [,<type1>] [,<typeN>] ) ;;
uResult = FWCallDLL32( cFarProc [,<uParam1>] [,<uParamN>] ) ;;
if ! Empty( _pOld ) ;;
_hDLL = _pOld ;;
end ;;
If( ValType( <DllName> ) == "N",, FreeLib32( _hDLL ) ) ;;
else ;;
MsgAlert( "Error code: " + LTrim( Str( _hDLL ) ) + " loading " + ;
If( ValType( <DllName> ) == "C", <DllName>, Str( <DllName> ) ) ) ;;
end ;;
return uResult
//----------------------------------------------------------------------------//
#endif
Re: xHarbour Commercial and latest FWH
Posted: Mon Aug 07, 2023 5:03 pm
by Randal
I put together a small test and if works fine with Fivewin and Harbour (Borland) but not xBuilder/xHarbour.
The problem is with LoadLibrary, this function returns a pointer instead of a numeric value.
I'm linking these libs:
\fwh\lib\xfw.lib
\xhb\lib\xHBZIP.LIB
\xhb\lib\xHBZipDll.lib
\xhb\c_lib\win\gdiplus.lib
I made sure I was including the most recent dll.ch however, when I linked in dll.c from the \fwh\source\winapi folder it now works. Perhaps there is another version of LoadLIbrary contained in one of the above libs.
Thanks,
Randal
Re: xHarbour Commercial and latest FWH
Posted: Tue Aug 08, 2023 4:07 am
by Antonio Linares
Dear Randal,
xHarbour provides a function LoadLibrary() that returns a pointer, thats why we modified dll.ch to check if a pointer is returned and then we turn it into a number.
When you link FWH dll.c then you are using FWH LoadLibrary() that retuns a number and everything is correct.
So, again, it seems as you are not using the most recent FWH dll.ch
Please double check it again, thanks