Deutsch
SDK-Helfer/ Tools

JRPC neuer Präkompiler für XProfan X4 - JRPC3

 
- Seite 1 -



Jens-Arne
Reumschüssel
Guten Abend zusammen,

ich bin kürzlich über das Problem gestolpert, dass XPSE eine ziemlich große Quelldatei von mir nicht mehr verarbeiten konnte. Variablen wurden plötzlich als nicht definiert gemeldet und andere "erratische" Probleme mehr. Ich könnte mir vorstellen, dass dies daran liegt, dass XPSE Schlüsselworte in Windows-Atoms verwaltet. Da ist irgendwann Schluss (bei irgendwas zwischen 60.000 und 70.000 Stück, wobei man bedenken muss, dass XPSE die Windows-API mit vorhält). Vielleicht ist es aber auch etwas ganz anderes, ich kann ja nicht in den "Maschinenraum" von XPSE schauen.

Jedenfalls blieb mir, da XPSE nicht mehr gepflegt wird, nichts anderes übrig, als das nachzubauen. Das Ergebnis ist JRPC3.

----- Features:

*vernünftige Meldung von Fehlern
*direkte Anzeige des Programmablaufes in XProfEd (sofern der unten erhältliche aufgebohrte XProfEd verwendet wird)
*Umsetzung der alten Profan-Syntax für Operatoren und alte Containerfunktionen
*extrem schnelle native fbPROCs, sofern man FreeBasic installiert hat (kostenlos, siehe Hilfe)
*mit fbPROCs kann zudem Inline-Assembler auch vor XProfan X4 realisiert werden
*extrem schnelle native pbPROCs, sofern man PureBasic installiert hat
*Echtzeitverfolgung von Variableninhalten
*einfache Zeitmessungen im Programmablauf
*Profan-Kompilerdirektiven funktionieren endlich vernünftig (z.B. Verschachtelung)
*eingebettete Variablen funktionieren auch mit Arrays
*die meisten WIN32-API-Funktionen sind bereits vordefiniert mitgeliefert
*API-Aufrufe über @external(...) werden automatisch in @call(...)-Aufrufe umgesetzt
*Einrückungsanalyse zum Finden von vertrackten Verschachtelungsfehlern
*Klammeranalyse zum Finden von vertrackten Klammerfehlern
*ENUMERATE-Funktionalität
*Assert zur Fehlerkontrolle
*es können beliebige DLLs in die XProfan-EXE integriert werden, sodass sie nicht mit ausgeliefert werden müssen (siehe {$WrapDll})
*einfaches Killen von mit JRPC3 gestarteten Programmen (interpretiert, .prc gestartet, .exe gestartet)
*extrem schnell (und daher natürlich nicht in XProfan geschrieben, da eine interpretierte Sprache hierfür naturgemäß viel zu langsam ist)
*beim Start von JRPC3 bereits vorhandene .prc-Dateien können zum Starten und Linken genutzt werden (es wird ein Hinweis angezeigt, dass es sich um ein altes Kompilat handelt)
*der Profan-Compiler kann zur Beschleunigung mit hoher Prozessorpriorität aufgerufen werden
*eingebauter Update-Checker mit Download, falls es ein Update gibt (Hilfe --> online nach Updates suchen)
*64- oder 32-bit-Version verfügbar (einfach JRPC3_64.exe oder JRPC_32.exe als Interpreter in XProfEd hinterlegen [Optionen --> Allgemeine Einstellungen] und JRPC3 mit F7 starten) - Achtung, die 64-bit-Version erzeugt natürlich keine 64-bit-XProfan-Programme, da XProfan das nicht kann, sondern JRPC3 selbst wird als 64-bit-Programm ausgeführt
*XProfan X4-Syntax verfügbar (möglicherweise noch nicht alles, da ich vermutlich nicht alles davon benutze, aber ich habe mich um Vollständigkeit bemüht - jedenfalls sind z.B. HASH-Arrays und QUADINTs dabei)
*Interpreter, PRCs und EXEs können mit Kommandozeilenparametern ausgeführt werden
*Interpreter, PRCs, EXEs und XPSE können mit Administratorrechten ausgeführt werden
*Prozeduren, die in dem aktuellen Programm zwar enthalten sind, aber nicht verwendet werden, werden aus der umgesetzten Datei entfernt, um die Dateigröße des Kompilats möglichst klein zu halten
*Variablen, die in dem aktuellen Programm zwar enthalten sind, aber nicht verwendet werden, werden aus der umgesetzten Datei entfernt, um die Dateigröße des Kompilats möglichst klein zu halten und den Speicherverbrauch zu optimieren
*nPROCs aus XPSE werden automatisch mit XPE zu einer DLL umgesetzt und die Aufrufe der nPROCs im Programm entsprechend angepasst, sofern XPSE vorhanden ist
*fast alles aus XPSE funktioniert auch in JRPC3 ({$NOERR}, {$(PRE)BATCH}, {$PUSHKEYWORD}, Interpreter, Runtime und Compiler festlegen, Shorties, ...)
*XProfEd_JR mit Quelltext-AutoComplete
*XProfEd_JR mit Quelltext-Memory-Funktion (Markierungen, zu denen zurückgesprungen werden kann)

Einschränkungen:
-kein XPSE-Inline-Assembler, wohl aber XProfan-Inline-Assembler (darin allerdings keine Prüfungen auf Korrektheit des Codes)
-ABER: man kann XPSE aus JRPC3 heraus aufrufen, sodass diese Funktionalität weiterhin verfügbar ist, sofern man XPSE besitzt (neuer Shorty: {$x})
-Variablen, die in einer Prozedur nicht deklariert sind, sondern "aus der aufrufenden Prozedur übernommen werden", sind standardmäßig nicht zugelassen (XProfan erlaubt das, aber so etwas ist genauso tödlich wie GOTO-Anweisungen). Bitte alle zu nutzenden Inputs als Parameter übergeben, und wenn etwas aus dem aufrufenden Programmteil verändert werden muss, beim Aufruf als Parameter z.B. @addr(x&) verwenden und in der Prozedur parameters x# und LONG x#,0=y& nutzen.
Wenn man aber unbedingt "vererbte" Variablen nutzen möchte, kann man dies mit der Kompilerdirektive {$Declare...} tun.

*als Hommage an XPSE lautet die Endung der Ausgabedatei ".enh3"

Eine genauere Erläuterung der einzelnen Features ist der chm-Hilfedatei zu entnehmen, die im Programm unter Hilfe --> Hilfedatei anzeigen oder mit F1 verfügbar ist.

----- /Features

Herunterladen und installieren:
JRPC3 kann unten heruntergeladen werden (setup_jrpc3.exe oder als ZIP-Datei).
Als Installationsverzeichnis bitte das XProfan-Stammverzeichnis angeben, also dasjenige, in dem die Dateien PROFAN.EXE, PROFCOMP.EXE, PRFRUN32.EXE etc. liegen. Alternativ kann die ZIP-Datei heruntergeladen und deren Inhalt manuell ins XProfan-Stammverzeichnis kopiert werden.

Einrichtung:
JRPC3_64.exe oder JRPC_32.exe als Interpreter in XProfEd hinterlegen [Optionen --> Allgemeine Einstellungen] und JRPC3 mit F7 starten.

Alle Befehle sind mit dem Befehl "h" wie "Hilfe" abrufbar und sollten selbsterklärend sein.

Für viele erweitere Features, die XProfEd betreffen, wie z.B. jenes, die Zeile, in der ein Fehler auftrat, direkt in XProfEd anzeigen zu können, ist der mitinstallierte XProfEd_JR erforderlich. Dafür muss man also XProfEd_JR.exe statt XProfEd.exe als Editor benutzen. Als "goody" gibt es dazu, dass beim Auf- und Zufalten von Programmen ein Fortschrittsanzeiger integriert ist (das kann bei großen Programmen ja bekanntlich ein bisschen dauern).

Es mag sein, dass noch nicht alles perfekt funktioniert. Ich bitte hierfür um Nachsicht. Meine  Programme lassen sich umsetzen, aber das muss noch lange nicht heißen, dass dies mit Programmen anderer Autoren, die jeder so ihre Eigenheiten haben, auch funktioniert.

Fehlermeldungen und Verbesserungsvorschläge gerne an jreumsc@web.de oder hier im Forum.

Beste Grüße, Jens-Arne

2.584 kB
Bezeichnung:JRPC3
Version:10.29
Kurzbeschreibung: JRPC3-Installer
Hochgeladen:15.02.2021
Ladeanzahl363
Herunterladen
1.699 kB
Bezeichnung:XProfEd_JR
Version:5.2
Kurzbeschreibung: Alte Version ohne AutoComplete zur Sicherheit
Hochgeladen:15.02.2021
Ladeanzahl224
Herunterladen
3.777 kB
Bezeichnung:JRPC3
Version:10.29
Kurzbeschreibung: ZIP-Datei statt Installer
Hochgeladen:02.04.2021
Ladeanzahl291
Herunterladen
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
16.02.2021  
 



 
- Seite 23 -


« Dieser Beitrag wurde als Lösung gekennzeichnet. »

- Seite 15 -



Jens-Arne
Reumschüssel
Es gibt eine neue Version, die anders mit dem internen Messagehandling umgeht. Bitte probier die mal aus. Vielleicht ist das Problem damit behoben.
 
XProfan X4
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
24.09.2022  
 




funkheld
Wie wird das bitte in Pb umgesetzt?

nProc getCircP(long r,w)
return long(sin(0.0174532925199433*float(w)/1000.0)*float(r))
endproc

Danke.
Gruss
 
14.05.2023  
 




Jens-Arne
Reumschüssel
Ich denke, so:

declare r!,w!

pbProc getCircP(*r,*w)
protected r.d,w.d
r=PeekD(*r)
w=PeekD(*w)
procedurereturn sin(0.0174532925199433*w/1000.0)*r
endproc

cls
r!=2
w!=3
print getCircP(@addr(r!),@addr(w!))
waitinput
end

Aber ist es wirklich sinnvoll, einen Integerwert zurückzugeben? Sollte das nicht besser auch ein Float sein? So etwa:

declare r!,w!,result!

pbProc getCircP(*r,*w,*result)
protected r.d,w.d
r=PeekD(*r)
w=PeekD(*w)
PokeD(*result,sin(0.0174532925199433*w/1000.0)*r)
endproc

cls
r!=2
w!=3
getCircP(@addr(r!),@addr(w!),@addr(result!))
print result!
waitinput
end

Oder noch einfacher mit Shared-Variablen:

declare r!,w!,result! shared

pbProc getCircP()
result!=sin(0.0174532925199433*w!/1000.0)*r!
endproc

cls
r!=2
w!=3
getCircP()
print result!
waitinput
end
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
14.05.2023  
 




funkheld
Danke für deine schnelle Hilfe.

Werde es noch einmal testen.

Danke.
 
14.05.2023  
 




Walter
Freue mich über JRPC3, habe nun aber ein Problem mit einem array.
JRPC3_64.exe läuft problemlos durch, der nachfolgend gestartete Interpreter bricht jedoch ab mit "Das Element gibt es nicht!".

Wenn ich das Programm gleich im Profan-Interpreter starte, läuft es problemlos durch.
' Array-Test / Shuffle
' Mischt die Einträge der Listboxliste
cls
randomize
' Listboxliste mit Strings füllen
clearlist
addstring(0,"BlaBla1")
addstring(0,"BlaBla2")
addstring(0,"BlaBla3")
addstring(0,"BlaBla4")
addstring(0,"BlaBla5")
listbox$("Start",1)
shuffle()
listbox$("Ergebnis",1)
end
'---------------------

proc shuffle

    '---------------------
    ' Mischt die Einträge der Listboxliste
    declare anz%
    anz%=getcount(0)
    Declare i%,nr%,L$[anz%]
    clear L$[]
    i%=0

    While i% < anz%' Durch die Listboxliste

        nr%=rnd(anz%)' Einen zufälligen Platz im Array wählen

        while L$[nr%]<>""' schon besetzt? Dann den nächsten freien Platz suchen

            inc nr%
            case nr%=anz%: nr%=0' falls am Ende: von vorne weg neu probieren

        wend

        L$[nr%]=getstring$(0,i%)
        Inc i%

    wend

    clearlist
    move("ArrToList",L$[])

endproc' shuffle


Woran liegt das?
 
15.05.2023  
 




Jens-Arne
Reumschüssel
Das hatte etwas damit zu tun, dass Du ein Array über eine Variable dimensioniert hast (Declare ...,L$[anz%]). In diesem Fall müssen kurze Variablennamen und immer global definierte Variablen in JRPC3 ausgeschaltet werden, was nun automatisch geschieht. Jetzt sollte Dein Programm also laufen.
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
15.05.2023  
 




Walter
Super! Danke!
 
15.05.2023  
 




Jens-Arne
Reumschüssel
Version 9.08a:

Map-Daten erzeugen:
Fehler, die während der Umsetzung eines Codes mit JRPC3 festgestellt werden, werden bekanntlich direkt von JRPC3 an der richtigen Stelle im Quellcode angezeigt (wenn der mitglieferte XProfEd_JR genutzt wird).
Wenn allerdings zur Laufzeit eines Programmes ein Fehler auftritt (z.B. eine Überschreitung des Dimensionierungsbereichs eines Arrays), gibt XProfan nur eine knappe Laufzeit-Fehlermeldung aus, die aber oft wenigstens eine Zeilennummer enthält. Diese Zeilennummer bezieht sich jedoch leider auf den kumulierten Code, den XProfan abarbeitet, sodass es fast unmöglich ist, die ausgegebene Zeilennummer einer Zeilennummer im Quelltext und dazu auch noch der richtigen Quelltextdatei (z.B. einer INC-Datei) zuzuordnen.
Hierbei helfen Map-Daten. Wenn diese Option aktiviert ist, schreibt JRPC3 mit, woher jede einzelne Zeile des Endcodes in der .enh3-Datei stammt, sodass die kumulierten Zeilennummern wieder ihrem Ursprung zugeordnet werden können.
Wenn ein XProfan-Laufzeitfehler mit einer darin gemeldeten Zeilennummer auftritt, kann man nun über das Menü "Datei" --> "Laufzeitfehlerzeile finden" die von XProfan ausgegebene Zeilennummer eingeben und erhält in XProfEd_JR die Zeile aus der richtigen Quelldatei angezeigt, in der der Fehler auftrat.
Das funktioniert allerdings nur, wenn vorher in den Optionen von JRPC3 die Map-Daten-Erzeugung aktiviert wurde. Dies kann auch noch nach Auftreten des Laufzeitfehlers geschehen, sofern der Programmcode nicht ergänzt oder gekürzt wurde, was natürlich die ermittelte Zeilennummer beeinflussen würde.
Wenn die Map-Daten gerade nicht mehr gebraucht werden, sollte diese Option wieder deaktiviert werden, weil sie den Quelltext um extrem viele Kommentare erweitert und damit den Interpreter von XProfan langsamer macht.
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
16.05.2023  
 




Jens-Arne
Reumschüssel
Hier ein ausführliches Beispiel für die Nutzung von fbPROCs für das schnelle Vorgeben von beliebig vielen vordefinierten Wörtern in Edit-Controls.
Die Vorgaben stehen jeweils in einer GridBox, wobei für verschiedene Edit-Controls unterschiedliche GridBoxen verwendet werden können. Es werden fbPROCs verwendet, damit nicht nur diejenigen, die PureBasic besitzen, das ausprobieren können.

Ganz am Anfang in FBGLOBAL bei #include muss der jeweils zutreffende Pfad angegeben werden. Denn es wird die Bibliothek commctrl.bi gebraucht, um die API-Konstanten für ListViews benutzen zu können.

declare _hE%,_hE2%,_hGB%,_hGB2%,_ende%,_s$,_ws#

'{ 'fbPROCs
FBGLOBAL
#include "D:\Programme\FreeBasic\inc\win\commctrl.bi" 'hier muss der richtige Pfad angegeben werden
dim shared as integer _MaxNum=0,_MinLaenge=1
redim shared as integer _NumhGB(0 to 1)
redim shared as string _OldAktEntry(0 to 1)
dim shared as string _KeywordEnders
_KeywordEnders=" .,:-+*/\!;"
ENDFBGLOBAL

fbPROC AmendEditText(byval hE as integer,byval hGB as integer,byval CaseSensitive as integer) as integer export
dim as byte pointer pAktEntry
dim as string AktEntry,Vorgabe,s2,AktSubStr,LeftPart,RightPart
dim as integer i,CurPos,erg,num
dim as zstring pointer zs,zs2
'{ 'Nummer der GB ermitteln
num=0
for i=1 to _MaxNum
if _NumhGB(i)=hGB
num=i
exit for
endif
next i
if num=0
_MaxNum=_MaxNum+1
num=_MaxNum
redim preserve _NumhGB(0 to num)
redim preserve _OldAktEntry(0 to num)
_NumhGB(num)=hGB
_OldAktEntry(num)=""
endif
'}
'{ 'aktuellen Eintrag ermitteln
pAktEntry=allocate(10001)
sendmessage(cast(handle,hE),WM_GETTEXT,10000,cast(integer,pAktEntry))
AktEntry=Peek(zstring,pAktEntry)
deallocate(pAktEntry)
'}
if AktEntry<>_OldAktEntry(num)
if len(AktEntry)>len(_OldAktEntry(num))
CurPos=loword(sendmessage(cast(handle,hE),EM_GETSEL,0,0))
'{ 'aktuellen Substring ermitteln
AktSubStr=""
for i=CurPos to 0 step -1
if i>0
if instr(_KeywordEnders,mid(AktEntry,i,1))<>0
LeftPart=left(AktEntry,i)
exit for
else
AktSubStr=mid(AktEntry,i,1)+AktSubStr
endif
else
LeftPart=""
endif
next i
for i=Curpos+1 to len(AktEntry)
if instr(_KeywordEnders,mid(AktEntry,i,1))<>0
RightPart=right(AktEntry,len(AktEntry)-(i-1))
exit for
else
AktSubStr=AktSubStr+mid(AktEntry,i,1)
endif
next i
'}
if len(AktSubStr)>=_MinLaenge
i=LVFindText(hGB,AktSubStr,-1)
if i>=0
Vorgabe=LVGetText(hGB,i)
if CaseSensitive
if left(Vorgabe,len(AktSubStr))=AktSubStr
erg=1
else
erg=0
endif
else
if ucase(left(Vorgabe,len(AktSubStr)))=ucase(AktSubStr)
erg=1
else
erg=0
endif
endif
if erg
if len(AktSubStr)<>len(Vorgabe)
s2=LeftPart+Vorgabe+RightPart
zs=Allocate(len(s2)+1)
poke zstring,zs,s2
sendmessage(cast(handle,hE),WM_SETTEXT,0,cast(integer,zs))
sendmessage(cast(handle,hE),EM_SETSEL,len(LeftPart)+len(AktSubStr),len(LeftPart)+len(Vorgabe))
deallocate(zs)
endif
endif
endif
endif
endif
_OldAktEntry(num)=AktEntry
endif
return 0
ENDPROC 'AmendEditText

fbPROC SetMinLaenge(byval Laenge as integer) as integer export
_MinLaenge=Laenge
if _MinLaenge<1
_MinLaenge=1
endif
return 0
ENDPROC 'SetMinLaenge

fbPROC SetKeywordEnders(byval Text as zstring pointer) as integer export
_KeywordEnders=peek(zstring,Text)
return 0
ENDPROC 'SetKeywordEnders

'{ 'Hilfsfunktionen
fbPROC LVGetCount(byval hLV as integer) as integer
return sendmessage(cast(any pointer,hLV),LVM_GETITEMCOUNT,0,0)
ENDPROC 'LVGetCount
fbPROC LVFindText(byval hLV as integer,byval text as string,byval StartLine as integer) as integer 'search is case insensitive
dim as LVFINDINFOA LVFI
dim as zstring pointer zs
dim as integer erg
LVFI.flags=LVFI_PARTIAL OR LVFI_STRING
zs=allocate(len(text)+1)
poke zstring,zs,text
LVFI.psz=zs
erg=sendmessage(cast(any pointer,hLV),LVM_FINDITEM,StartLine,cast(integer,@LVFI))
deallocate(zs)
return erg
ENDPROC 'LVFindText
fbPROC LVGetText(byval hLV as integer,byval Zeile as integer,byval Spalte as integer=0) as string
dim as LVITEM LVI
dim as string ret,s
dim as zstring pointer LVItemText
'LVI=mask&,iItem&,iSubItem&,state&,stateMask&,pszText&,cchTextMax&,iImage&,lParam&,iIndent&,iGroupId&,cColumns&,puColumns&,piColFmt&,iGroup&
LVItemText=Allocate(2001)
LVI.iItem=Zeile
LVI.iSubItem=Spalte
LVI.mask=LVIF_TEXT
LVI.pszText=LVItemText
LVI.cchTextMax=2000
sendmessage(cast(any pointer,hLV),LVM_GETITEMTEXT,Zeile,cast(integer,@LVI))
ret=peek(zstring,LVItemText)
deallocate(LVItemText)
return ret
ENDPROC 'LVGetText
'}
'}

'*** Hauptprogramm
WindowStyle 1+2+4+8+512
cls
_hE%:=@create("EDIT",%HWnd,"",10,10,300,20)
dim _ws#,1000
widestring _ws#,0="Automarken"
@sendmessage(_hE%,~EM_SetCueBanner,0,_ws#) 'lParam: 0=Hinweis nur anzeigen, wenn das Editfeld nicht den Fokus hat (default); 1=auch anzeigen, wenn fokussiert
_hE2%:=@create("EDIT",%HWnd,"",10,40,300,20)
widestring _ws#,0="rund um den Fernseher"
@sendmessage(_hE2%,~EM_SetCueBanner,0,_ws#) 'lParam: 0=Hinweis nur anzeigen, wenn das Editfeld nicht den Fokus hat (default); 1=auch anzeigen, wenn fokussiert
dispose _ws#
_hGB%:=@create("GRIDBOX",%HWnd,"1;0;0",1,0,0,0,0) 'sortiert, damit Einträge alphabetisch sortiert vorgegeben werden
@sendmessage(_hGB%,~WM_SETREDRAW,0,0) 'beschleunigt das Füllen der Gridbox deutlich, außerdem ist sie sowieso unsichtbar
@addstring(_hGB%,"BMW"):@addstring(_hGB%,"Audi"):@addstring(_hGB%,"VW"):@addstring(_hGB%,"Skoda"):@addstring(_hGB%,"Nissan")
@addstring(_hGB%,"Honda"):@addstring(_hGB%,"Chevrolet"):@addstring(_hGB%,"Mini"):@addstring(_hGB%,"Mercedes")
@addstring(_hGB%,"Opel"):@addstring(_hGB%,"Alfa"):@addstring(_hGB%,"Romeo"):@addstring(_hGB%,"Aston"):@addstring(_hGB%,"Martin")
@addstring(_hGB%,"Bentley"):@addstring(_hGB%,"Bugatti"):@addstring(_hGB%,"Buick"):@addstring(_hGB%,"Cadillac"):@addstring(_hGB%,"Chrysler")
@addstring(_hGB%,"Citroen"):@addstring(_hGB%,"Dacia"):@addstring(_hGB%,"Daihatsu"):@addstring(_hGB%,"Dodge")
_hGB2%:=@create("GRIDBOX",%HWnd,"1;0;0",1,0,0,0,0) 'sortiert, damit Einträge alphabetisch sortiert vorgegeben werden
@sendmessage(_hGB2%,~WM_SETREDRAW,0,0) 'beschleunigt das Füllen der Gridbox deutlich, außerdem ist sie sowieso unsichtbar
@addstring(_hGB2%,"Fernseher"):@addstring(_hGB2%,"Programm"):@addstring(_hGB2%,"Programmzeitschrift"):@addstring(_hGB2%,"Serie")
@addstring(_hGB2%,"Sender"):@addstring(_hGB2%,"Fernbedienung")
usermessages $10
SetMinLaenge(1) 'minimale Länge des eingegebenen Textfragments, ab der die Vorgaben hinzugefügt werden
_s$=" "
SetKeywordEnders(@addr(_s$)) 'nur " " als Endzeichen für Suchstrings definieren (default=" .,:-+*/\!;")
@setfocus(%HWnd)
_ende%=0
whilenot _ende%
waitinput
AmendEditText(_hE%,_hGB%,0) '0=case insensitive, 1=case sensitive
AmendEditText(_hE2%,_hGB2%,0) '0=case insensitive, 1=case sensitive
if @iskey(27) or (%uMessage=$10)
_ende%=1
while @iskey(27)
sleep 25
endwhile
endif
endwhile
end
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
21.05.2023  
 




Walter
Habe leider wieder ein Problem:
Verwende hashes.dll, um für eine Datei die MD5-Prüfsumme zu berechnen. [...] 
Geprüft wird einfach irgendein Text in der Datei Prüfdatei.txt.
Funktioniert mit dem normalen Interpreter problemlos - mit JRPC3 gibt es allerdings ein No Return beim Start des Interpreters mittels i (auch, wenn ich {$NoLocal2GlobalVarConversion} verwende).
' Test von hashes.dll
 {$NoLocal2GlobalVarConversion}
declare Dat$,dll2&,Pfad$
cls
Pfad$=GetDir$("")
dll2&=UseDLL(Pfad$+"\\hashes.dll")
DEF testit(3) ! "hashes.dll","testit"
' Prüfdatei
Dat$=Pfad$+"\\Prüfdatei.txt"
'
Prüfsumme(Dat$)
'
FreeDLL dll2&
end
'---------------------

proc Prüfsumme

    '---------------------
    ' Berechnen der Prüfsumme einer Datei mittels MD5.pcu
    parameters Prüfdatei$
    declare T&,T$,Datei$
    Datei$ = Prüfdatei$' Hier muss durch eine lokale Variable eine lokale Adresse erzeugt werden
    ' in die Datei "MD5" wird der MD5 reingeschrieben
    ' der steht aber auch in t$
    t& =  testit(addr(Datei$),"MD5",chr$(0))
    t$ =  string$(t&,0)
    ' MD5 der Datei steht auch in t$
    messagebox(t$,"MD5",0)

endproc' Prüfsumme

 
21.05.2023  
 




Jens-Arne
Reumschüssel
Hallo Walter,

hier ist das "chr$(0)" beim Funktionsaufruf von testit(...) das Problem. JRPC3 erzeugt standardmäßig einen external-Aufruf. Da funktioniert die Typumwandlung von Strings in String-Adressen für chr$(...) von XProfan offenbar nicht, bei der DEF-Definition aber schon. Es ist an dieser Stelle übrigens relativ sinnfrei, chr$(0) zu benutzen, weil daraus binär exakt 0 wird. Schreibe also:

t& = testit(addr(Datei$),"MD5",0)

Dann funktioniert es auch mit JRPC3.

Wenn Du das chr$(0) beibehalten willst, kannst Du die Umwandlung von DEF-Funktionen in external-Funktionen auch ausschalten: {$NoDef2ExternalConversion}

Um das Grundproblem zu verstehen, muss man wissen, dass die Parameter von DLLs *immer* 4 Bytes breit sind (in 32bit-Programmen). Also ist auch der Parameter "MD5" eigentlich völlig unbrauchbar. Er ist zwar zufällig auch 4 Bytes breit (drei Buchstaben und das Nullbyte am Ende), aber im binären Sinne kommt dabei nichts Sinnvolles heraus. Die DLL erwartet nämlich einen Pointer auf einen String (welcher 4 Bytes breit ist), weil man Strings selbst halt nicht als DLL-Parameter verwenden kann. XProfan wandelt diesen Parameter aber intern in sowas wie @addr(»String, in dem "MD5" steht«) um, deshalb merkt man diesen Programmierfehler normalerweise nicht. Nur für @chr$(...) scheint diese Umwandlung jedenfalls bei external-Aufrufen nicht zu funktionieren, wie oben schon erwähnt.

{$NoLocal2GlobalVarConversion} wird in diesem Beispiel übrigens in keiner Variante gebraucht.

Gruß, Jens-Arne
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
21.05.2023  
 




Walter
Danke!
 
21.05.2023  
 




Jens-Arne
Reumschüssel
Ich habe mir jetzt den Funktionsaufruf der DLL nochmal genauer angesehen. In der readme-Datei steht:

?_Hash(Datei$ | bereich#,Algorithmus$[[,start&],size&])

Die Funktion "testit" wird nicht beschrieben, sie ist aber die einzige Funktion, die die DLL exportiert. Vermutlich ist der letzte Parameter "start&", denn sonst würde "0" keinen Sinn machen. In diesem Fall wäre eine Typumwandlung von chr$(0) in einen String-Pointer auf einen String mit einem Null-Byte tödlich, weil da irgendein riesiger Integerwert rauskommen würde (eben die Adresse auf den String). Eine Integer-Zahl wie "0" scheint daher die einzig sinnvolle Variante zu sein. Warum es mit DEF trotzdem funktioniert, ist mir ein Rätsel.

Vielleicht ist es genau andersherum: bei DEF wird nicht in einen String-Pointer umgewandelt, bei external schon. Wie auch immer, da sollte ein numerischer Wert stehen, kein String.

Gruß, Jens-Arne
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
21.05.2023  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

62.337 Betrachtungen

Unbenanntvor 0 min.
Manfred Barei25.09.2024
Jens-Arne Reumschüssel18.09.2024
Gast.081529.08.2024
R.Schneider23.08.2024
Mehr...

Themeninformationen



Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie