xHarbour Commercial and latest FWH

Post Reply
Randal
Posts: 260
Joined: Mon Oct 24, 2005 8:04 pm

xHarbour Commercial and latest FWH

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 42259
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: xHarbour Commercial and latest FWH

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Randal
Posts: 260
Joined: Mon Oct 24, 2005 8:04 pm

Re: xHarbour Commercial and latest FWH

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 42259
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: xHarbour Commercial and latest FWH

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply