DllExecuteCallEx - Call a dll function allowing NIL parameters

Top  Previous  Next

Syntax

 

<nResult> := DllExecuteCallEx( <cCallTemplate> [, <xParams1..n>] )

 

Parameters

 

<cCallTemplate>

 

<cCallTemplate> is a binary character string which was returned by the function DllPrepareCall().

 

<xParams1..n>

 

<xParams1..n> is the list of parameters to be passed as arguments to the dll function. The types of the arguments must match the ones required by the called function. Please see DllExecuteCall() and DllCall() in the Xbase++ documentation for details.

 

Return value

 

DllExecuteCalEx returns the return value of the executed dll function. If the dll supports the Xbase++ calling convention, the value can be of any Xbase++ data type. Otherwise, the return value is numeric.

 

Description

 

DllExecuteCallEx is a replacement for the DllExecuteCall() function of Xbase++. It fixes problems with NIL parameters present in Xbase++ versions  before 1.90 and it takes down the last O/S error code after the call. This error code can be retrieved with GetLastError() and set with SetLastError().  stores the last DllExecuteCall() has a problem in Version 1.82 when NIL parameters are passed to it while  DLL_CALLMODE_COPY is selected. In this case the GC of your application is stopped for the time the call is active. DllExecuteCallEx resolves this problem. With this behaviour the optional parameters in adapter functions, that are automatically defaulted to NIL, can be directly passed on to the wrapped dll functions.

 

#Including "DllCallFix.ch" in your source files will change every call to DllExectuteCall() to DllExecuteCallEx.

 

Classification

 

Core

 

Category

 

Calls and Callbacks

 

Quick Info

 

Library: cckptcor.lib /cckptcor.dll

Header: DllCallFix.ch

 

Example

 

 

#INCLUDE "dll.ch"

#INCLUDE "CockpitCoreLibs.ch"

 

* Commenting out this line will stop the GC when the second MessageBox is

* displayed. Use TaskMgr.exe to see how your application turns into a memory hog.

#INCLUDE "DllCallFix.ch"

 

FUNCTION main

 

LOCAL dll,dllcall

 

* Start a thread producing load for the GC

Thread():New():Start({||Stress()})

 

* Give the other thread some time to start

Sleep(100)

 

* Let's pick a function that does not return immediately

dll := DllLoad("user32.dll")

dllcall := DllPrepareCall(dll,DLL_STDCALL + DLL_CALLMODE_COPY,"MessageBoxA")

 

* This will work like a charm

DllExecuteCall(dllcall,0,"GC works properly now.","GC Tester", 0x1000)

 

* This will stop the GC while the MessageBox is displayed

DllExecuteCall(dllcall,NIL,"GC is now inoperative.","GC Tester", 0x1000)

 

RETURN NIL

 

 

 

FUNCTION Stress(p1,p2,p3)

 

LOCAL n,xyz

 

DO WHILE .T.

 

  * Some work for the GC

  FOR n := 1 TO 1000

      xyz := { Space(1000) + Space(500) + Space(3000),;

               Space(1000) + Space(500) + Space(3000),;

               Space(1000) + Space(500) + Space(3000),;

               Space(1000) + Space(500) + Space(3000) }

  NEXT n

 

  * Some time to recover

  Sleep(100)

 

ENDDO

 

RETURN NIL