Question about converting a function pointer to a delegate
Posted: Tue Sep 13, 2022 10:26 am
Hello everybody!
I need your help again.
I'm having trouble converting a function pointer from VO to a delegate in XSharp.
The function worm_export_tar of the WORMAPI.DLL of the german "Kassensicherungsverordnung" needs a functionpointer to export data from the securitymodul (TSE = technische Sicherheitseinrichtung).
WORMAPI.DLL was created by Swissbit who developed the TSE system.
WORMAPI.DLL is not under my control and I assume that the functions it contains will work correctly.
The worm_export_tar function makes multiple calls to a callback function and passes a memory pointer containing the data to be written to the export file.
In VO the following code works fine:
METHOD ExportTar(cDateiname AS STRING) AS INT PASCAL CLASS WormAccess
LOCAL hFile AS PTR
LOCAL nRet AS INT
nRet := -1
IF !(SELF:hWormContext == NULL_PTR)
hFile := FCreate(cDateiname, FC_NORMAL)
IF !(hFile == F_ERROR)
//The pointer to the callback function is passed here
nRet := worm_export_tar(SELF:hWormContext, @CallbackExportWormTar(), hFile)
FClose(hFile)
ELSE
nRet := -2
ENDIF
ENDIF
RETURN nRet
//This is the callback-funkction which writes the data to the export-file:
STATIC FUNCTION CallbackExportWormTar(hDaten AS PTR, nLen AS DWORD, hFile AS PTR) AS INT
LOCAL nRet AS INT
IF FWrite3(hFile, hDaten, nLen) == nLen
nRet := 0
ELSE
nRet := -1
ENDIF
RETURN nRet
STATIC GLOBAL hProc_worm_export_tar AS TF_worm_export_tar PTR
FUNCTION TF_worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN 0
FUNCTION worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN PCALL(hProc_worm_export_tar, hWormContext, hCallbackFunktion, hFile)
In XSharp, the following code crashes exactly and reproducibly the third time the callback function is called. No error box is displayed, the program is simply terminated. The only difference between VO and XSharp is that XSharp uses the delegate to invoke the callback function.
DELEGATE CallbackExportWormTar_delegate(hDaten AS PTR, nLen AS DWORD, hFile AS PTR) AS INT
METHOD ExportTar(cDateiname AS STRING) AS INT PASCAL
LOCAL hFile AS PTR
LOCAL nRet AS INT
STATIC LOCAL oCallbackExportWormTarDelegate AS CallbackExportWormTar_Delegate
nRet := -1
IF !(SELF:hWormContext == NULL_PTR)
hFile := FCreate(cDateiname, FC_NORMAL)
IF !(hFile == F_ERROR)
oCallbackExportWormTarDelegate := CallbackExportWormTar
nRet := worm_export_tar(SELF:hWormContext, System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(oCallbackExportWormTarDelegate), hFile)
FClose(hFile)
ELSE
nRet := -2
ENDIF
ENDIF
RETURN nRet
STATIC FUNCTION CallbackExportWormTar(hDaten AS PTR, nLen AS DWORD, hFile AS PTR) AS INT
LOCAL nRet AS INT
IF FWrite3(hFile, hDaten, nLen) == nLen
nRet := 0
ELSE
nRet := -1
ENDIF
RETURN nRet
STATIC GLOBAL hProc_worm_export_tar AS TF_worm_export_tar PTR
FUNCTION TF_worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN 0
FUNCTION worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN PCALL(hProc_worm_export_tar, hWormContext, hCallbackFunktion, hFile)
In both cases (VO and XSharp) the hProc_worm_export_tar variable is initialized once when the TSE system is started:
hLibWorm := LoadLibrary(String2Psz("wormapi.dll"))
hProc_worm_export_tar := GetProcAddress(hLibWorm, String2Psz("worm_export_tar"))
So the question is: What is wrong with the delegate or the callback-function in XSharp what works fine in VO? What's weird is that it works twice and crashes on the third call in XSharp.
Regards
Kai
I need your help again.
I'm having trouble converting a function pointer from VO to a delegate in XSharp.
The function worm_export_tar of the WORMAPI.DLL of the german "Kassensicherungsverordnung" needs a functionpointer to export data from the securitymodul (TSE = technische Sicherheitseinrichtung).
WORMAPI.DLL was created by Swissbit who developed the TSE system.
WORMAPI.DLL is not under my control and I assume that the functions it contains will work correctly.
The worm_export_tar function makes multiple calls to a callback function and passes a memory pointer containing the data to be written to the export file.
In VO the following code works fine:
METHOD ExportTar(cDateiname AS STRING) AS INT PASCAL CLASS WormAccess
LOCAL hFile AS PTR
LOCAL nRet AS INT
nRet := -1
IF !(SELF:hWormContext == NULL_PTR)
hFile := FCreate(cDateiname, FC_NORMAL)
IF !(hFile == F_ERROR)
//The pointer to the callback function is passed here
nRet := worm_export_tar(SELF:hWormContext, @CallbackExportWormTar(), hFile)
FClose(hFile)
ELSE
nRet := -2
ENDIF
ENDIF
RETURN nRet
//This is the callback-funkction which writes the data to the export-file:
STATIC FUNCTION CallbackExportWormTar(hDaten AS PTR, nLen AS DWORD, hFile AS PTR) AS INT
LOCAL nRet AS INT
IF FWrite3(hFile, hDaten, nLen) == nLen
nRet := 0
ELSE
nRet := -1
ENDIF
RETURN nRet
STATIC GLOBAL hProc_worm_export_tar AS TF_worm_export_tar PTR
FUNCTION TF_worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN 0
FUNCTION worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN PCALL(hProc_worm_export_tar, hWormContext, hCallbackFunktion, hFile)
In XSharp, the following code crashes exactly and reproducibly the third time the callback function is called. No error box is displayed, the program is simply terminated. The only difference between VO and XSharp is that XSharp uses the delegate to invoke the callback function.
DELEGATE CallbackExportWormTar_delegate(hDaten AS PTR, nLen AS DWORD, hFile AS PTR) AS INT
METHOD ExportTar(cDateiname AS STRING) AS INT PASCAL
LOCAL hFile AS PTR
LOCAL nRet AS INT
STATIC LOCAL oCallbackExportWormTarDelegate AS CallbackExportWormTar_Delegate
nRet := -1
IF !(SELF:hWormContext == NULL_PTR)
hFile := FCreate(cDateiname, FC_NORMAL)
IF !(hFile == F_ERROR)
oCallbackExportWormTarDelegate := CallbackExportWormTar
nRet := worm_export_tar(SELF:hWormContext, System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(oCallbackExportWormTarDelegate), hFile)
FClose(hFile)
ELSE
nRet := -2
ENDIF
ENDIF
RETURN nRet
STATIC FUNCTION CallbackExportWormTar(hDaten AS PTR, nLen AS DWORD, hFile AS PTR) AS INT
LOCAL nRet AS INT
IF FWrite3(hFile, hDaten, nLen) == nLen
nRet := 0
ELSE
nRet := -1
ENDIF
RETURN nRet
STATIC GLOBAL hProc_worm_export_tar AS TF_worm_export_tar PTR
FUNCTION TF_worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN 0
FUNCTION worm_export_tar(hWormContext AS PTR, hCallbackFunktion AS PTR, hFile AS PTR) AS INT PASCAL
RETURN PCALL(hProc_worm_export_tar, hWormContext, hCallbackFunktion, hFile)
In both cases (VO and XSharp) the hProc_worm_export_tar variable is initialized once when the TSE system is started:
hLibWorm := LoadLibrary(String2Psz("wormapi.dll"))
hProc_worm_export_tar := GetProcAddress(hLibWorm, String2Psz("worm_export_tar"))
So the question is: What is wrong with the delegate or the callback-function in XSharp what works fine in VO? What's weird is that it works twice and crashes on the third call in XSharp.
Regards
Kai