Page 1 of 1

xHarbour Commercial and latest FWH

PostPosted: 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

PostPosted: Sat Aug 05, 2023 3:02 pm
by Antonio Linares
Dear Randal,

Your dll.ch must contain this:
Code: Select all  Expand view
            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 view
// 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

PostPosted: 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

PostPosted: 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