PDA

View Full Version : GetLastError feature



DirectuX
02-02-2020, 20:04
Following on from https://www.thinbasic.com/community/showthread.php?13026-asynchronous-file-operations,

many windows functions return an error code that should be accessible via the GetLastError function (https://docs.microsoft.com/fr-fr/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror). That is the case by example of CopyFileExW function (https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-copyfileexw) or the DeviceIoControl function (https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol).

I've found nothing about this in the samples nor the help file: how can a thinBasic script get this error code and relevant messages ?

Petr Schreiber
02-02-2020, 21:47
Hi DirectuX,

I think as of now, you need to use:


DECLARE FUNCTION GetLastError IMPORT "KERNEL32.DLL" ALIAS "GetLastError" () AS DWORD


As this is super useful function, I think Eros could consider adding it to its WIN_ wrappers as WIN_GetLastError?

It would be also nice to have all the errors from WinError.h, I can help with that if needed.


Petr

DirectuX
02-02-2020, 21:51
Thanks Petr !

+ I agree for the wrapper :drink:

ErosOlmi
03-02-2020, 08:23
Problem with GetLastError API is that it return ... last error of a Windows API call.

But inside an interpreted language like thinBasic ... between you call to a Window Api and GetLastError call there could be other thousands of Windows Api calling by the interpreter.
So GetLastError is, for the most cases, useless in thinBasic. It depends how you write code, when GetLastError is called compared to the API calling.
thinBasic has to do a lot of things just after a Window API calling so when thinBasic parser has reached GetLastError ... it may be late.

Instead GetLastError is useful in a compiled language where the code call exactly what the programmer write (well, most of the time)

DirectuX
03-02-2020, 11:13
Problem with GetLastError API is that it return ... last error of a Windows API call.

But inside an interpreted language like thinBasic ... between you call to a Window Api and GetLastError call there could be other thousands of Windows Api calling by the interpreter.
So GetLastError is, for the most cases, useless in thinBasic. It depends how you write code, when GetLastError is called compared to the API calling.
thinBasic has to do a lot of things just after a Window API calling so when thinBasic parser has reached GetLastError ... it may be late.

Instead GetLastError is useful in a compiled language where the code call exactly what the programmer write (well, most of the time)


Not that way :D

Note : nf-errhandlingapi-getlasterror (https://docs.microsoft.com/fr-fr/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) 'The last-error code is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error code.


In help file:

DECLARE

Syntax
DECLARE {SUB | FUNCTION} ProcName LIB "LibName" ALIAS "AliasName" [([Arguments])] [AS ReturnType] *

Parameters


Name
Type
Optional
Meaning


bLastErrorAware
Boolean
Yes
Enable immediate GetLastError retrieving




WIN_GetLastError

Syntax
n = WIN_GetLastError

Parameters
no parameter

Returns
number
n = the error code number (https://docs.microsoft.com/fr-fr/windows/win32/debug/system-error-codes) set by the last Windows API function/sub or 3rd party external DLL function call


WIN_FormatMessage

Syntax
s = WIN_FormatMessage(nSysErrorCode)

Parameters


Name
Type
Optional
Meaning


nSysErrorCode
number
No
System error code number



Returns
string
s = the message definition corresponding to the error code number provided as parameter


In thinBasic core (thinCore.dll):

... Pseudo script-interpretation ...
IF (LastErrorAware is %TRUE) detected THEN ' Could be pre-parsing but not compulsorily

STATIC lastExternalErrorCode as NUMBER
DECLARE [B]ONCE FUNCTION GetLastError IMPORT "KERNEL32.DLL" ALIAS "GetLastError" () AS DWORD ' Retrieves the calling thread's last-error code value.
DECLARE ONCE FUNCTION FormatMessage IMPORT "KERNEL32.DLL" ALIAS "FormatMessage" () AS NUMBER
ENDIF

IF some (Windows API function/sub or 3rd party external DLL function) is called by script THEN
... make the call ...
... right after the call, ... GetLastError ' Now lastExternalErrorCode contains the last error code
ENDIF

IF WIN_GetLastError is called in script THEN

Return lastExternalErrorCode as result
ENDIF

(...)

* Or even simpler, it can be a global modifier :

DECLARE GetLastError

Syntax
#DEFAULT DECLARE GetLastError{%TRUE | %FALSE}

Parameters
no parameter

Returns
Nothing



Eros, this is oriented towards a solution for this thread (https://www.thinbasic.com/community/showthread.php?13026-asynchronous-file-operations). I hoped for a word on this at least from you :)