Page 1 of 3

FWH 10.1 - DLL32 Function

PostPosted: Wed Feb 17, 2010 7:52 pm
by don lowenstein
I'm upgrading from older FWH version using xharbour version .99

the DLL32 function PPO code reveals a call to GetProcAddress() - "OLD Convention"

in the new FWH 10.1 the same DLL32 function PPO code reveals a call to GetProcAdd() -- "NEW Convention"

in the OLD convention, this function returned a binary string used with CallDLL() function.

in newer FWH libraries, this same call results in a value of data type "Pointer" -- I have never seen a datatype "Pointer" before and wonder what exactly it is and how it's used, defined, etc.

anyway, the NEW convention uses GetProcAdd() instead of GetProcAddress() to return the binary string.

I ask because I am getting GPF's while calling a C-Language .DLL file, which always worked fine in old FWH / XHarbour.

What's the difference with new DLL calling convention in CALLDLL() between .99 xharbour FWH libraries and 1.2 xharbour FWH libraries?

in the meantime I will try to build a simple example to get more information.

thank you.

Re: FWH 10.1 - DLL32 Function

PostPosted: Wed Feb 17, 2010 8:56 pm
by Antonio Linares
Don,

DLL32 gets translated into DLL, as DLL32 was developed for 16 bits apps. The syntax to use is DLL FUNCTION ...

Whats the DLL FUNCTION declaration that you are using ? Except for the GetProcAdd() change, everything should work fine as usual.

Re: FWH 10.1 - DLL32 Function

PostPosted: Wed Feb 17, 2010 10:28 pm
by don lowenstein
i can communicate with the c-language dll file if I use GetProcAdd()

If I use GetProcAddress() a "Pointer" is returned and I have no success with the DLL - GPF every time.

I'm using a DLL (IMAGE2PDF.DLL from Utility Warrior - you can down load it).
This is a DLL that receives parms and/or returns info.

If I call the DLL without passing parms, no problem using DLL FUNCTION and/or manually calling getprocadd() and calldll() calling convention.

But, If I attempt to PASS PARAMETERS to the DLL I get a GPF. I've tried passing strings - LPSTR, and integer values - LONG

These functions work great with fwh 2006 and xHarbour Compiler build 0.99.51 (SimpLex)

I think there is a difference in the GetProcAdd() and CallDll() functions in FWH between the "OLD" and "NEW" FWH.

do you have any c-language dll's that receive parms that you can test? if not, I can supply one that I know for sure works fine.

thanks.

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 12:53 am
by Antonio Linares
Don,

GetProcAddress() is a function declared in Harbour/xHarbour, thats why we had to rename ours to GetProcAdd(). If you use FWH DLL FUNCTION command then you have to use GetProcAdd(). It will not work with the other.

What xHarbour version are using ? Are you using Borland C to compile ?

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 1:22 am
by don lowenstein
borland 5.5 c++
xharbour 1.2.1 ( shipped with FWH 10.1 )


i confirm 100% that GetProcAdd() is the appropriate call for xharbour 1.2.1 when using calldll() function. :)

In my coding, if I don't pass any parameters to a .DLL function - no problem. works perfectly.

But - if I MUST pass parameters to a .DLL function, then I get a GPF every time, using my
new configuration of xharbour 1.2.1 and FWH 10.1.

If I use EXACT SAME .DLL AND EXACT XHAROBUR SOURCE CODE for xharbour 0.99.51 and FWH 2006,
it works perfectly, with or without passing parameters from calling code to the .DLL function.

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 9:19 am
by Antonio Linares
Don,

Please post here the DLL FUNCTION ... sentence that you have declared and how you are using it, thanks

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 1:52 pm
by dbmanfwh
Dear Antonio,

Whenever I upgrade xHarbour errors I have experienced.
Dll32 Function in FWH so without the use of xHabour dllcall () function is used.

Code: Select all  Expand view
    DLL32 STATIC FUNCTION UserLogin( UserCode      AS STRING,;
                                     UserPasswd    AS STRING,;
                                     @UserName     AS STRING,;
                                     @ReqPhone1    AS STRING,;
                                     @ReqPhone2    AS STRING,;
                                     @ReqPhone3    AS STRING,;
                                     @TotalPrice   AS LONG  ,;
                                     @CallPrice    AS _INT   ) AS _INT LIB  AppSMSCall.dll
     ........

     nRet := UserLogin( ::cId, ::cPass, @::cUser, @::cReqTel1, @::cReqTel2, @::cReqTel3, @::nTotAmt, @::nPrice)

=>

      #define DC_CALL_STD       0x0020
     
      nRet := DllCall("AppSMSCall.dll", DC_CALL_STD, "UserLogin", ;
                     ::cId, ::cPass, @::cUser, @::cReqTel1, @::cReqTel2, @::cReqTel3, @::nTotAmt, @::nPrice)
 


Regards
bsm

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 2:43 pm
by Enrico Maria Giordano
Try

Code: Select all  Expand view
    DLL STATIC FUNCTION USERLOGIN( UserCode    AS LPSTR,;
                                   UserPasswd  AS LPSTR,;
                                   @UserName   AS LPSTR,;
                                   @ReqPhone1  AS LPSTR,;
                                   @ReqPhone2  AS LPSTR,;
                                   @ReqPhone3  AS LPSTR,;
                                   @TotalPrice AS LONG,;
                                   @CallPrice  AS LONG ) AS LONG FROM "UserLogin" LIB "AppSMSCall.dll"


EMG

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 4:42 pm
by don lowenstein
Here is code for my xHarbour 1.2.1 and BCC 5.5 and FWH 10.1

The actual dll can be downloaded from http://www.utilitywarrior.com/Image-to-PDF-Dynamic-Link-Library.htm

From that web-page, click the "download link" at the bottom of the page.

Code: Select all  Expand view


STATIC HLIB

#INCLUDE "FiveWin.ch"

Function Main()

local retval, parm1

 hLib := LoadLibrary( "f:\utility\IMAGE2PDF.DLL" )      // set hdll to a handle so recursive loads not required in dll32 function.

// THESE 2 CALLS WORK - no parameters passed within the declaration below
retval := I2PDF_SilentRunning( )       // RETURNS NIL DUE TO VOID DECLARATION BELOW
retval := I2PDF_GetDLLVersion( )       // RETURNS 240 - PROPER Integer returned from DLL


// These 2 calls DO NOT WORK due to passing a parameter.
retval := I2PDF_SetDPI( 0 )            
retval := I2PDF_License( "XXX-ZZZZ-AAAAA-BBBBBB-CCCCCCC" )

FreeLibrary( hLib )


RETURN NIL


**********************************************************

// DLL API proptotypes - 1st 2 functions work as they don't pass parms.
//                       the 2nd one properly returns an interger (240) - proving communication with DLL
//                       3rd and 4th calls both produce GPF - common denominator is passing a parm.

DLL STATIC FUNCTION I2PDF_SilentRunning( ) AS LONG;
   PASCAL FROM "I2PDF_SilentRunning" LIB hLib

DLL STATIC FUNCTION I2PDF_GetDLLVersion( ) AS LONG;
   PASCAL FROM "I2PDF_GetDLLVersion" LIB hLib

DLL STATIC FUNCTION I2PDF_SetDPI( nDpi AS LONG ) AS LONG;
   PASCAL FROM "I2PDF_SetDPI" LIB hLib
 
DLL STATIC FUNCTION I2PDF_License( cLicCode AS LPSTR) AS VOID;
   PASCAL FROM "I2PDF_License" LIB hLib
   



 

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 4:44 pm
by Antonio Linares
Don,

Please try to remove PASCAL from the declaration of those two functions that are failing.

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 5:32 pm
by don lowenstein
Good News - Bad News

Removing PASCAL from all calls results in:

*************************************
-- pass an integer ( LONG ) parm - SUCCESS!!!!

retval := I2PDF_SetDPI( 0 )

DLL STATIC FUNCTION I2PDF_SetDPI( nDpi AS LONG ) AS LONG;
FROM "I2PDF_SetDPI" LIB hLib

***********************************
-- Pass a character string ( LPSTR ) -- GPF.

retval := I2PDF_License( "XXX-ZZZZ-AAAAA-BBBBBB-CCCCCCC" )

DLL STATIC FUNCTION I2PDF_License( cLicCode AS LPSTR) AS VOID;
FROM "I2PDF_License" LIB hLib

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 6:29 pm
by Enrico Maria Giordano
Try to call I2PDF_License() alone. It doesn't GPF.

EMG

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 7:11 pm
by don lowenstein
Unfortunately, I must provide the license parameter for proper usage.

i wonder if the "big string" has some sort of ramification?

Is the definition of LPSTR appropriate?

retval := I2PDF_License( "XXX-ZZZZ-AAAAA-BBBBBB-CCCCCCC" )

DLL STATIC FUNCTION I2PDF_License( cLicCode AS LPSTR) AS VOID ;
FROM "I2PDF_License" LIB hLib

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 7:28 pm
by Enrico Maria Giordano
Yes, it is. But what I did want to point out is that if it works alone then the declaration must be correct.

EMG

Re: FWH 10.1 - DLL32 Function

PostPosted: Thu Feb 18, 2010 8:54 pm
by don lowenstein
I have discovered the nature of the problem!!!! :D

With the PASCAL parm in the DLL function definition, all calls were successful until I tried one using parameters. The 1st call with parameters caused the GPF.

After removing the PASCAL keyword in the DLL function definition, I was able to call a function successfully with parameters, ONCE. But, I could NOT call the DLL after that, regardless of the function, parameters, etc.

Regarding the function in question in prior postings ---- retval := I2PDF_License( "XXX-ZZZZ-AAAAA-BBBBBB-CCCCCCC" )
I successfully called the I2PDF_License( cString ) function, without the PASCAL keyword, passing a character parameter as LPSTR.
I'm sure all functions within the DLL work fine because I've used this DLL for several years.

Here is the nature of the problem with a code snippet to support my suspscion.

If no parms are passed - the DLL can be called as often as needed.
As soon as the DLL is called ONE TIME with a Parameter, ALL SUBSEQUENT CALLS, regardless of which function, produce a GPF.

It seems as if passing a parameter ONCE causes the process to fail on subsequent attempts.

I wonder if the CallDLL() function is not "starting fresh" each time, or maybe has some
info/garbage alive from the prior call, or something like that?


Code: Select all  Expand view

// no PASCAL keyword on any DLL Function declarations
for i := 1 to 1000
   retval := I2PDF_GetDLLVersion( )
   retval := I2PDF_SilentRunning( )
   retval := I2PDF_MetaTextFitBoundingRect( )    
   retval := I2PDF_MetaMargins( )    
   retval := I2PDF_UseEMFDeviceSize( )
   retval := I2PDF_MetaToNativePDF( )
next

retval := I2PDF_License( "XXX-ZZZZ-AAAAA-BBBBBB-CCCCCCC" )   // works fine without a PASCAL keyword.  

// GPF on the next line of code - notice this call worked 1000 times before!
retval := I2PDF_GetDLLVersion( )     //  ===> GPF on 1st call AFTER calling DLL with a parameter.