TSE-Kasse Pointer in C-Funktionen Swissbit

Fragen rund um diverse Windows-Versionen, ihr Verhalten unter Xbase++ und den Umgang mit der API

Moderator: Moderatoren

miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

In den Funktionen von Swissbit-TSE in der wormApi.dll werden an mancher Stelle Pointer verlangt. Beisp.:
worm_info_tseSerialNumber ( const WormInfo * info, const unsigned char ** serialNumber, worm_uint * ;
serialNumberLength )
Das Problem ist der char** -Pointer für die Seriennummer. Ich habe schon vieles versucht. Ich rufe die Funktion über EXTERN auf
EXTERN CDECL worm_info_tseSerialNumber(info AS INTEGER64, @serialNumber AS INTEGER64 , serialNumberLength as integer );
in WormAPI.dll // habe es auch mit @serialNumber AS String versucht.
Hier der eigentliche Funktionsaufruf:
local serialnumber:=space(32) //sie ist 32 Byte lang
local nsernumberlng, npointer, sernrLng
npointer:=_pgrab(serialnumber, @sernrLng) //CHARPointer aus ot4xb
//npointer ist eine Zah und sernrLng ist 32+1
xvar:= worm_info_tseSerialNumber(info, @npointer, nsernumberlng ) //info ist vorher durch info_new() und info_read()
//initialisiert und funktioniert bei anderen Info-Funktionen
ERgebnis Programmabsturz mit folgenden Fehlern:Internal data structures corrupted, :gencode 41:subcode5
VALTYPE: C VALUE: _DLL
-> VALTYPE: N VALUE: 6426768 //der Wert von info
//wird der Pointer mit Referenz als Integer64 oder String übergeben dann
->Valtype: N 32
//-> VALTYPE: N VALUE: 1934375456 //Pointerwert bei Übergabe ohne Referenz
-> VALTYPE: N VALUE: 32 //Seriennummernlänge
Ich weiß nicht mehr weiter! Hat jemand eine Idee? An diesem Problem könnte mein TSE-Einbindung scheitern!
aus allgemeine Fragen hat geschrieben: TSE-Kasse Pointer in C-Funktionen Swissbit
#1 Beitrag von miwe-pos » Do, 05. Mär 2020 23:53

In den Funktionen von Swissbit-TSE in der wormApi.dll werden an mancher Stelle Pointer verlangt. Beisp.:
worm_info_tseSerialNumber ( const WormInfo * info, const unsigned char ** serialNumber, worm_uint * ;
serialNumberLength )
Das Problem ist der char** -Pointer für die Seriennummer. Ich habe schon vieles versucht. Ich rufe die Funktion über EXTERN auf
EXTERN CDECL worm_info_tseSerialNumber(info AS INTEGER64, @serialNumber AS INTEGER64 , serialNumberLength as integer );
in WormAPI.dll // habe es auch mit @serialNumber AS String versucht.
Hier der eigentliche Funktionsaufruf:
local serialnumber:=space(32) //sie ist 32 Byte lang
local nsernumberlng, npointer, sernrLng
npointer:=_pgrab(serialnumber, @sernrLng) //CHARPointer aus ot4xb
//npointer ist eine Zah und sernrLng ist 32+1
xvar:= worm_info_tseSerialNumber(info, @npointer, nsernumberlng ) //info ist vorher durch info_new() und info_read()
//initialisiert und funktioniert bei anderen Info-Funktionen
ERgebnis Programmabsturz mit folgenden Fehlern:Internal data structures corrupted, :gencode 41:subcode5
VALTYPE: C VALUE: _DLL
-> VALTYPE: N VALUE: 6426768 //der Wert von info
//wird der Pointer mit Referenz als Integer64 oder String übergeben dann
->Valtype: N 32
//-> VALTYPE: N VALUE: 1934375456 //Pointerwert bei Übergabe ohne Referenz
-> VALTYPE: N VALUE: 32 //Seriennummernlänge
Ich weiß nicht mehr weiter! Hat jemand eine Idee? An diesem Problem könnte mein TSE-Einbindung scheitern!
Nach oben
Zuletzt geändert von brandelh am Fr, 06. Mär 2020 7:44, insgesamt 1-mal geändert.
Grund: gleiche Anfragen aus verschiedenen Bereichen ins richtige Forum kopiert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von AUGE_OHR »

hi,
miwe-pos hat geschrieben: Do, 05. Mär 2020 18:01 In den Funktionen von Swissbit-TSE in der wormApi.dll werden an mancher Stelle Pointer verlangt. Beisp.:
worm_info_tseSerialNumber ( const WormInfo * info, const unsigned char ** serialNumber, worm_uint * ;
serialNumberLength )

Hier der eigentliche Funktionsaufruf:
local serialnumber:=space(32) //sie ist 32 Byte lang
local nsernumberlng, npointer, sernrLng

npointer:=_pgrab(serialnumber, @sernrLng) //CHARPointer aus ot4xb
//npointer ist eine Zah und sernrLng ist 32+1
xvar:= worm_info_tseSerialNumber(info, @npointer, nsernumberlng ) //info ist vorher durch info_new() und
die Ot4xb Syntax ist falsch

Code: Alles auswählen

@ DLL-Name:Function()

@user32:DestroyIcon( ::Handle )
ich halte "WormInfo" für eine Structure. es müsste eine API Beschreibung geben (meisten in *.H Dateien)

Code: Alles auswählen

BEGIN STRUCTURE WormInfo
   MEMBER LPSTR serialNumber
   MEMBER DWORD cbSize
END STRUCTURE
einen genügend grossen leeren String, mit CHR(0) am Ende, übergibt man per Referenz.

Code: Alles auswählen

#include "OT4XB.CH "

LOCAL oWI := WormInfo():New()
LOCAL cSN := SPACE(32)+CHR(0)

   @wormApi:worm_info_tseSerialNumber(oWI, @cSN, 32)
---

es ist ja ein xBase Forum und da gibt es nicht viele die sich mit API oder C beschäftigen.

p.s. wormApi.dll ist eine 32 Bit DLL :?:
gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

char müsste ein 8 bit string sein, keinesfalls eine Integer.
CONST ist eine Konstante, also kein @ Zeichen in Xbase++ übergeben

Wenn es ein String ist, sollte es genügen einfach die Stringvariable als solche oder den String als Parameter anzugeben ...

in der Hilfe zu EXTERN ist unten bei [@] ... TYPE die Liste der möglichen TYPEN der Parameterbeschreibung angegeben, ähnlich der bei der Rückgabe type der DLL (immer die richtige Tabelle nehmen):

Code: Alles auswählen

[@] <Parameter> AS <Type> 

Specifies the name and the data type of the parameters passed to the DLL function. The data type of the parameters expected by the DLL function must be specified following the keyword AS using one of the following key words. 

Parameter types of DLL functions 
Key word	Description		 	Corresponding C/SDK types (examples) 
SHORT		16 bit integer	 		SHORT, short int 
USHORT		Unsigned 16 bit integer		USHORT, unsigned short 
INTEGER		32 bit integer 			BOOL, int 
LONG 		32 bit integer 			INT32 
UINTEGER 	Unsigned 32 bit integer		DWORD, LPDWORD, LPARAM, PVOID, HANDLE, HWND, UINT, ULONG 
INTEGER64 	64 bit integer 			INT64 
UINTEGER64 	Unsigned 64 bit integer		UINT64, ULONG64, DWORD64 
SINGLE		32 bit floating point 		FLOAT32, float 
DOUBLE 		64 bit floating point 		FLOAT64 
STRING 		Character string 		LPSTR, PSZ, char, char* 
IDISPATCH 	COM/ActiveX object (IDispatch) 	IDispatch* 
CALLBACK 	Callback function 		WNDENUMPROC, DLGPROC 
CALLBACKA 	Asynchronous callback function 	WNDPROC, HOOKPROC 
XPPVALUE 	An arbitrary Xbase++ value (not applicable) 
Das ist dein Typ und ohne @ da keine Rückgabe erwartet wird:

STRING Character string Für Xbase Extern !!! ist das alles das Gleiche: LPSTR, PSZ, char, char*
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von Jan »

Ein wenig OT: ich denke, diese Diskussion gehört nicht in die Wissensbasis. Die Wissensbasis ist das Teilen von Wissen und Erkenntnissen mit den anderen Entwicklern., Aber nicht Problem-Diskussionen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

Stimmt, keine Wissensbasis ... 3 Einträge über dieser Nachricht habe ich die Parameter von Extern erklärt, wenn man die Hilfe liest und weiß um was es in API / C Dlls geht, sollte das kein Problem sein.

Die gleiche Anfrage unter Allgemein lösche ich und dieses Thema habe ich unter Windows API (ist auch C-DLL von fremden Herstellern gemeint) verschoben.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von AUGE_OHR »

hi,

Xbase v2.x scheint was DLL angeht ja einiges gelernt zu haben =D>
wie sieht es mit Structure aus, wird BAP noch benötigt :?:
gruss by OHR
Jimmy
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Zuerst einmal lieber Brandelh, gehe bitte davon aus, dass ich die Anleitungen zu Extern gelesen habe; ob ich sie verstanden habe, ist eine andere Frage. Dass XBASE ++ nicht aus einem Guss ist, dazu gleich ein Beispiel:
EXTERN STDCALL worm_tse_runSelfTest(WormContext AS INTEGER64, clientid AS STRING) in WormAPI.dll //dazu der Aufruf
xvar:=worm_tse_runSelfTest(WormContext, clientID)
Ergebnis Programmabsturz oError:args :
-> VALTYPE: C VALUE: _DLL ÝpFÝ
-> VALTYPE: N VALUE: 1536760 //wormcontext
-> VALTYPE: C VALUE: 4711 //ClientID
oError:description : Internal data structures corrupted
oError:genCode : 41
oError:operation : dllExecuteCall
oError:severity : 2
oError:subCode : 5
Nun der Programmaufruf mit dllcall mit den gleichen Werten:
xvar:=dllcall("wormapi.dll",DLL_STDCALL,"worm_tse_runSelfTest", Wormcontext,clientID)
Kein Programmabsturz - xvar=0 d.h. erfolgreich ausgeführt!!

Nun zum eigentlichen Problem - Zeiger - zuerst Aufruf mit EXTERN
EXTERN STDCALL worm_info_tseSerialNumber(info AS INTEGER64,@serialNumber AS STRING ,;@serialNumberLength as integer );
in WormAPI.dll
xvar:= worm_info_tseSerialNumber(info,@TSESERNUMBER,@sernrlng )
Ergebnis Programmabsturz oError:args :
-> VALTYPE: C VALUE: _DLL ç :ç
-> VALTYPE: N VALUE: 1539744 //Worminfo ein Pointer der von worm_info_new zurückgegeben wird
-> VALTYPE: C VALUE: 32Leerzeichen
-> VALTYPE: N VALUE: 32
oError:description : Internal data structures corrupted
oError:genCode : 41
oError:operation : dllExecuteCall
oError:severity : 2
oError:subCode : 5

Nun der Aufruf über dllcall:
xvar:=dllcall("wormapi.dll",DLL_STDCALL,"worm_info_tseSerialNumber",info,@TSESERNUMBER,@sernrlng )

Kein Absturz! Rückgabe: xvar=268999696 und TSESERNUMBER binär 58 5F 17 00 und dann 28x die 20 für Leerzeichen!
Das scheint zuerst einmal schön zu sein doch leider völlig falsch! Da war ich schon vor 3 Wochen. Die richtige Seriennummer müsste so
lauten:"f884917c6f18938adf2b299eb45bae5f94e0dd7ecd5f6fa77a15cb042d83f61b"

Fazit: Mit Werteübergabe per Referenz habe ich nicht den char**-Pointer der benötigt wird. Und Jan es geht mir sehr wohl um Wissensbasis.
Das ist ein Problem der Einbindung der Swissbit-TSE. Auch wenn ich mich erst vor Kurzen neu angemeldet habe, meine Anmeldedaten von Anfang der 2000-er habe ich verschlampt, war damals Mitglied der Berliner/Brandenburger Gruppe, bin ich mit fast 76 kein "grüner Junge". Habe seit
Anfang der 80-er Jahre programmiert (BASIC,DBASE,TurboPascal, C auf DOS-Basis und dann durch Arbeitsplatzwechsel ab 1991 Clipper und daher als Folge XBASE++. War mein Fehler solange nicht im Forum gewesen zu sein. Hab vielleicht dadurch an manchen Stellen das "Fahrrad" zum zweiten Mal erfinden müssen.
Es geht um das Problem TSE in Kasse unter XBASE++ einzubinden!!! Offensichtlich ist damit noch keiner im Forum fertig!!
Vielleicht finden wir gemeinsam eine Lösung??
Beste Grüße an Alle
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Hallo Jimmy,
Deine Frage hab ich fast vergessen.
Anscheinend Ja, da die Pointer-Frage noch nicht geklärt ist.

GRuß
Michael
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von AUGE_OHR »

hi,
miwe-pos hat geschrieben: Sa, 07. Mär 2020 19:09 Deine Frage hab ich fast vergessen.
Anscheinend Ja, da die Pointer-Frage noch nicht geklärt ist.
bist du dir sicher das es sich um eine 32 Bt DLL handelt :?:
diese kleine v1.9.355 App kann das feststellen
dll6432.zip
for Xbase++ v1.9.355
(3.1 KiB) 370-mal heruntergeladen
gruss by OHR
Jimmy
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Hallo Jimmy,

Die Doku von Swissbit ist auch nicht so erhellend.
Ich habe die API aus dem Verzeichnis \swissbit\sdk\c\windows32-stdcall\bin genommen 41.984 Byte lang. Dort sind auch die
Testprogramme WormCli.exe und WormGui.exe. Im Verzeichnis ..\c\windows32\bin ist sie 37.888 Byte lang.
Beide habe ich ausprobiert die Letztere mit Aufrufkonvention CDECL. Die allgemeinen Funktionen haben mit dllcall() bei beiden
funktioniert. Nur nicht die mit char**-Pointer als Übergabeparameter.
Die 64-er DLL hat eine Länge von 45.056 Byte; ich habe sie nie probiert! Alle haben das Erstellungsdatum 04.02.2020.
Wenn es Dich interessiert, kann ich Dir das ganze SDK gepackt zusenden.

Gruß
Michael
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von AUGE_OHR »

hi,

wenn es ein 32 und 64 Bit Verzeichniss gibt dann sollte man die 32 Bit erwischen.
schon mal mit was anderem als CDECL wie DLL_OSAPI versucht :idea:
gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

miwe-pos hat geschrieben: Sa, 07. Mär 2020 19:06 Zuerst einmal lieber Brandelh, gehe bitte davon aus, dass ich die Anleitungen zu Extern gelesen habe; ob ich sie verstanden habe, ist eine andere Frage.
wenn ich davon ausgehe dass jemand die Anleitung gelesen hat, bin ich in den meisten Fällen auf dem falschen Dampfer. 8)

DLLCALL() Aufrufe sind der altmodische Vorgänger von EXTERN und können nicht verwendet werden wenn man komplexere Datentypen als Rückgabe will. (wobei ich die 1.90 im Kopf habe, muss ich mal bei 2.00 lesen ;-) )
DLLCALL() gibt immer nur einen LONG Wert zurück.
miwe-pos hat geschrieben: Sa, 07. Mär 2020 19:06 Fazit: Mit Werteübergabe per Referenz habe ich nicht den char**-Pointer der benötigt wird. Und Jan es geht mir sehr wohl um Wissensbasis.
Das ist ein Problem der Einbindung der Swissbit-TSE. ...
Es geht um das Problem TSE in Kasse unter XBASE++ einzubinden!!! Offensichtlich ist damit noch keiner im Forum fertig!!
Vielleicht finden wir gemeinsam eine Lösung??
Das ist das was Jan meinte, die fertige Lösung gehört in die Wissensbasis, die Irrwege und Fragen dazu nicht ;-)
Xbase 2.0 Anleitung hat geschrieben:DllCall()
Calls a DLL function dynamically at runtime.

The function is deprecated. Use the EXTERN command instead.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

Ich kenne diese DLL nicht, daher kann ich nur allgemein meinen Senf dazu geben:

Xbase unterstützt ausschließlich 32 Bit Versionen von DLLs.
EXTERN STDCALL worm_tse_runSelfTest(WormContext AS INTEGER64, clientid AS STRING) in WormAPI.dll
EXTERN CDECL worm_info_tseSerialNumber(info AS INTEGER64, @serialNumber AS INTEGER64 , serialNumberLength as integer ) in WormAPI.dll // habe es auch mit @serialNumber AS String versucht.
Ich habe die API aus dem Verzeichnis \swissbit\sdk\c\windows32-stdcall\bin *** wenn die DLL auch daraus ist, muss es STDCALL sein !
Zunächst muss bei Xbase++ immer geklärt werden, ob es eine DLL mit STDCALL (wohl alle API Funktionen) oder CDECL (wohl viele C-DLLs ...) ist !
Wenn man hier einen Fehler macht, werden die Parameter falsch eingelesen, was häufig mit einem FATAL ERR belohnt wird, es kann aber auch zu unerwünschten Ergebnissen kommen.
Bei Pablos OT4XB muss man das nicht angeben, er ermittelt den richtigen Typ. Ich habe nur mit seiner Klasse Erfahrungen damit.

Ich vermisse bei der EXTERN Angabe den TYP der Rückgabe der DLL Funktion.

@serialNumber AS String

wenn man hier einen @ angibt, dann nur wenn die DLL hier eine Rückgabe reinstellen soll.
wenn serialNumber ein String enthält, der gefüllt werden soll, muss die String-Variable vorher genügend groß sein, z.B. mit serialNumber := space(256) oder Replicate(chr(0), 15) ...
einfache API Funktionen liefern in diesen Fällen den String in dem per Referenz übergebenen String das Ergebnis zurück, z.B. das hier:

Code: Alles auswählen

nErr := FindExecutableA( cFile, cPath, @cExe )
if nErr > 32 // MSDN: Returns a value greater than 32 if successful, or a value less than or equal to 32 representing an error.
...
DLLFUNCTION FindExecutableA(cFile, cPath, @cEXE ) USING STDCALL FROM SHELL32.DLL
*** API Beschreibung für C++
HINSTANCE FindExecutableA(
  LPCSTR lpFile,
  LPCSTR lpDirectory,
  LPSTR  lpResult
);
Bei deiner DLL vermute ich aber eher, dass das Ergebnis in einer Struktur gefordert und geliefert wird, das macht die Sache komplexer.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

Frage, in welchen Programmiersprachen liegen Beispiele bei ?

Hier dein Code Beispiel einer Funktion:

Code: Alles auswählen

worm_info_tseSerialNumber ( const WormInfo * info, const unsigned char ** serialNumber, worm_uint * serialNumberLength )
ich habe mal nachgelesen um sicher zu gehen, was "unsigned char" bedeutet, in QuickPDF gab es immer nur w_char_t *, ich bin auch schon älter und hab vieles vergessen 8)
Wickipedia zu C-Datentypen hat geschrieben:Ein Character repräsentiert die kleinste adressierbare Einheit in C, in der Regel acht Bit.
... Je nach Compiler kann char entweder gleichbedeutend sein mit signed char (-128 bis 127, fast immer der Fall) oder mit unsigned char (0 bis 255).
Beim Extern Befehl und in der Doku zur QuickPDF habe ich keinen Parameter mit ** gefunden, immer nur max 1 * , (z.B. wchar_t* filename, hier muss man die ANSI Funktion aufrufen) ...
aber in LibXL (für die ich auch einen Wrapper geschrieben habe, den kann man hier auch herunter laden):
LibXL Doku C-Beschreibung hat geschrieben: bool saveRaw(const char** data, unsigned* size)
Saves a file to internal memory buffer. Parameters:
data - pointer to buffer;
size - pointer to saved size.
Returns false if error occurs. Get error info with Book::errorMessage().
Hier meine Umsetzung in XBase 1.90ff mit OT4XB, mit Hilfe von Pablo ;-)

Code: Alles auswählen

*--------------------------------------------------------------------------------
METHOD xlBook:BookSaveRaw(bData, nSize) // call BookSaveRaw( @cData, @nSize) 
   local uRet := nil, p := 0     
   nSize := 0                    
   uRet := FpQCall( {'LibXL','xlBookSaveRawA'},'__bo__sl_@sl_@ul',::hHandle,@p,@nSize ) 
   if uRet  .and. ! empty(p)     
      bData := PeekStr(p,,nSize) 
      nSize := len(bData)        
   endif                         
RETURN uRet                      
In Xbase aufrufen mit ... o:BookSaveRaw( @cData, @nSize)

uRet := FpQCall( {'LibXL','xlBookSaveRawA'},'__bo__sl_@sl_@ul',::hHandle,@p,@nSize )

dieser ot4xb Funktion kann man genau mitgeben, wie sie was zu behandeln hat, im String-Parameter ('__bo__sl_@sl_@ul'):
Die Aufrufekonvention ermittelt die Funktion selbst.

{'LibXL','xlBookSaveRawA'}, Array mit Name der DLL und Name der Funktion, immer ANSI Version nutzen, wenn es zwei gibt.

__bo = der erste Parameter ist der RückgabeTYP der Funktion, die weiteren beschreiben die TYPen der Parameter, hier wandelt ot4xb die Rückgabe 0 zu .f. und <> 0 to .t.
__sl = signed LONG Variable, unveränderbar, hier für den DLL Handle (::hHandle)
_@sl = signed LONG Variable, erhält den neuen Wert zurück, muss daher aus Xbase++ heraus auch mit @ aufgerufen werden (@p)
_@ul = unsigned LONG Variable, erhält den neuen Wert zurück, hier die Länge der Daten in bData', (@nSize )

Um die Daten aus dem Buffer zu bekommen dient dann die Funktion PeekStr() aus OT4XB ...

Wenn man das alles in eine eigene Klasse kapselt kann man den Aufruf von Xbase++ heraus einfach halten.
Ich selbst werden meine Klassen nicht mehr auf EXTERN umschreiben, die funktionieren gut wie sie sind und ich mag diese Funktion :-)

Keinesfalls sollte man alles mischen.
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von Martin Altmann »

Hubert,
zu Deiner impliziten "Frage":
* bedeutet bei den Parametern Pointer
** bedeutet dementsprechend Pointer auf Pointer.
Mit letzterem hat(te) Xbase++ schon immer Probleme (= ging nicht). Ob sich das bei neueren Versionen geändert hat, weiß ich nicht.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

stimmt, so war das ... ich sag ja vergessen 8)
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von AUGE_OHR »

hi,
brandelh hat geschrieben: Mo, 09. Mär 2020 7:03 Zunächst muss bei Xbase++ immer geklärt werden, ob es eine DLL mit STDCALL (wohl alle API Funktionen) oder CDECL (wohl viele C-DLLs ...) ist !
aus c:\ALASKA\XPPW32\Include\dll.ch

Code: Alles auswählen

// Konstanten der Aufrufkonventionen
#define  DLL_SYSTEM               4
#define  DLL_CDECL                8
#define  DLL_STDCALL             32
#define  DLL_XPPCALL            128
#ifdef   __OS2__
  #define DLL_OSAPI             DLL_SYSTEM
#else
  #define DLL_OSAPI             DLL_STDCALL
#endif
deshalb kam ich auf DLL_OSAPI was auch "andere" xBase-Dialekte verstehen
brandelh hat geschrieben: Bei deiner DLL vermute ich aber eher, dass das Ergebnis in einer Struktur gefordert und geliefert wird, das macht die Sache komplexer.
es handelt sich doch um ein "Sicherheits-Modul", oder :?:
es wäre schon verwunderlich wenn es "Hard-Codiert" in eine Datei steckt ...

es gibt am Anfang

Code: Alles auswählen

WormInfo * info
wie Hubert vermute ich dahinter eine Windows Strukture und eine eigene scheint man ohne BAP mit Xbase++ 2.x nicht erstellen zu können.
gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

Jimmy,

selbst ich werfe den OS/2 betreffenden Code in meinen PRG raus, daher nehme ich direkt den Wert für die Windows API ;-)
Gruß
Hubert
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Der Hinweis auf ot4xb gibt mir neue Möglichketen. Überall, wo Funktionen Zahlenwerte zurück geben,geht
@wormapi:<funktion>(parameter) sehr gut und ist eine Erleichterung beim Programmieren.
Doch was ist zu tun, wenn ein String als Rückgabe erwartet wird?

Die Sache mit dem Pointer char** konnte ich auch mit ot4xb noch nicht lösen. So ganz verstehe ich das Beispiel von
Brandelh nicht. Vielleicht könnte er mir mal die ganze Beispiel-Klasse zukommen lassen.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von brandelh »

alle meine Quellcodes stehen jedem in der Wissensbasis zur Verfügung und auf meiner Homepage.

Das Beispiel stammt von HBLibXL :arrow: viewtopic.php?f=16&t=7610&p=84578

im Quellcode wird der Pointer auf den Pointer durch die Peekstr() Funktion aufgelöst wird. Das ist eine OT4XB Funktion.

Code: Alles auswählen

if uRet  .and. ! empty(p)     
      bData := PeekStr(p,,nSize) 
      nSize := len(bData)        
endif
in dem Beispiel handelt es sich um binär Daten.

Die von vielen geliebte @ Syntax spart Schreibarbeit und es sieht der API sehr ähnlich,
Ich ziehe jedoch die von mir verwendete Funktion vor, da ich hier den Rückgabewert direkt bestimmen kann.
Pablos Klasse biegt dann die Rückgabewerte auf Xbase++ Format um oder man setzt diese in einer eigenen Funktion um ...
das mache ich z.b. wenn eine API logisch meldet, dann ist 0 zu .f. und <> 0 wird zu .t.

Braucht man für diese Worm API eigentlich die Hardware ?
Gruß
Hubert
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Hallo Hubert,
zuerst mal danke! Muß ich noch ausprobieren.
Für die wormapi gibt es einige wenige Funktionen mit Aufruf "void", die ohne die Hardware auskommen.
Ansonsten braucht man die Hardware. Ich habe den Entwickler-USB-Stick, der aber auch nur bis Ende Juli nutzbar ist.
Für die TSE der Bundesdruckerei kann man bei Jarltech eine MicroSD für Entwickler 40Tage leihweise erhalten.
Das ist dann die se-api-c-stdcall.dll oder se-api-c.dll.

Gruß
Michael
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Hallo an Alle,
ich habe es fast geschafft!

TSESERNUMBER:=space(32)
TSESERNUMBER:=_xGrab((TSESERNUMBER), @sernrlng)
xvar:=dllcall("wormapi.dll",DLL_STDCALL,;
"worm_info_tseSerialNumber",info,@TSESERNUMBER,@sernrlng )
//TSESERNUMMER gibt anscheinend wieder einen Pointer zurück
TSESERNUMBER:=PeekStr(TSESERNUMBER,,32) // Pointer to String
//String ist allerdings nicht 32 Byte sondern 160 Byte lang allerdings die letzten 32 Byte
//sind exakt die Seriennummer!!!
strfile(TSESERNUMBER,"TSESERNUM",.t.)
Ich probiere weiter, hoffe das Ergebnis noch zu verfeinern?!
Gruß
Michael
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Kurze Korrektur!
beim zweiten Test war der String exakt 32 Byte lang mit der exakten Seriennummer!!
Anscheinend war, da strfile(,,.t.), noch ein alter String vorher abgespeicht worden.
Damit die Pointer to Pointer (char**) - Frage gelöst!
Udo
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 46
Registriert: Do, 18. Okt 2007 15:37

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von Udo »

Hallo!

Gestern habe ich kurz die Swissbit TSE API von Alaska überflogen. Da scheint Alaska eine Menge Arbeit investiert zu haben. Wenn das so funktioniert wie es da steht, kann man sich bei Alaska nur bedanken. Hat das schon mal jemand mit dem Swissbit USB Stick getestet ?

Glück Auf!
Udo
miwe-pos
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 28
Registriert: Mi, 26. Dez 2018 18:13

Re: TSE-Kasse Pointer in C-Funktionen Swissbit

Beitrag von miwe-pos »

Hallo an alle,
Habe mein TSE-Programm Version Swissbit einschließlich aller Transaktionen mit Ausnahme der "worm_export_tar..-Funktionen fertig.
Diese Funktionen benötigen einen Zeiger(Pointer) auf eine WormExportTarCallback-Funktion.
Habe dafür eine solche geschrieben und in eine externe DLL gepackt:
function WormExportTarCallback(block,blocklen,data)
static nhandle:=0
local nwrite:=0
if nhandle=0
nhandle:=fcreate((data),0)
endif
if nhandle=-1
return 1
endif
nwrite:=fwrite(nhandle,block,blocklen)
if nwrite=blocklen
return 0
else
return -1
endif
return 0
// die Funktion testweise mit dllcall(...) aufgerufen funktioniert und legt eien Datei "TAREXPOR" an!!

Im Programm habe ich folgenten Code:
local block:=space(1024), blocklen:=1024, data:="TAREXPOR",nhandle,ctext,callback
nhandle:=DLLLoad("wmcall.dll") //laden der eignen Dll ->51838976
ctext:=DLLPrepareCall(nhandle,DLL_XPPCALL,"WormExportTarCallback")
callback:=nFpCall((ctext),block,siglng,data) // //Pointer auf Funktion -> Rückgabe: 1614283112
xvar:=dllcall("wormapi.dll",DLL_STDCALL, "worm_export_tar" , WormContext, callback , data ) //Absturz
//Fehler:
oError:args :
-> VALTYPE: C VALUE: _DLL Ö ]Ö
-> VALTYPE: N VALUE: 1456568 //wormContext
-> VALTYPE: N VALUE: 1614283112 //Pointer
-> VALTYPE: C VALUE: Tarexpor //data
oError:canDefault : N
oError:canRetry : N
oError:canSubstitute: Y
oError:cargo : NIL
oError:description : Internal data structures corrupted

Hat jemand eine Idee?

Beste Grüße
Michael (miwe-pos)
Antworten