ZitatDenn wenn ihr auf WLAN-Entfernung zusammen hockt, könnt ihr eh auch Kabel nehmen.
Wobei das Kabel bis zu 20x schneller ist, WENN man im selben Raum ist. Ist man durch Mauern oder lange Strecken getrennt, wirds mit WLAN noch schlimmer.
ZitatDenn wenn ihr auf WLAN-Entfernung zusammen hockt, könnt ihr eh auch Kabel nehmen.
Wobei das Kabel bis zu 20x schneller ist, WENN man im selben Raum ist. Ist man durch Mauern oder lange Strecken getrennt, wirds mit WLAN noch schlimmer.
"Früher", als es noch garkein WLAN gab, hat man einfach 2 Rechner mit einem sog. "Nullmodemkabel" miteinander verbunden. (RS232 bzw. serielle Schnittstelle)
Diese Verbindung kannte auch jedes Netzwerkprotokoll.
Heutzutage benutzt man Patchkabel (die früher gebräuchlichen Crossoverkabel sind nicht nötig) um 2 Rechner per RJ45 Buchse zu verbinden. Ein ordentliches Kabel vorrausgesetzt, ist eine Gigabitverbindung kein Thema. Und der "Stress" mit einem von einem Rechner aufgespannten WLAN (was genau IMMER dann wackelt, wenn man es am wenigsten brauchen kann) ist auch vergessen.
James,
genau aufgrund der von dir geposteten Microsoft-Statements zum Thema bin ich überzeugt, dass diese "sharable"-Geschichte überhaupt nicht im Sinne des Erfinders (bzw. der "neueren" BS) ist!
In sämtlichen von mir gelesenen Forenbeiträgen taucht irgendwann ein Microsoft-MVP auf und bestreitet vehement die von uns gezeigten Möglichkeiten.
Die innerhalb der DLL untergebrachten Funktionen werden natürlich nur einmal in den Speicher geladen, genau dafür ist das System DLL/LIB ja gemacht! Es gibt Konstruktionen, sogar mit mehreren Threads innerhalb eines Prozesses "eine" Funktion im Speicher zu benutzen. Alles andere wäre auch unsinnig. Sämtliche Betriebssystem-eigenen DLL´s stellen ihre Funktionen ja auch sämtlichen Programmen zur Verfügung.
Hat ggf. ein C/C++-Spezi eine Möglichkeit, diese "shareability" von Speicher innerhalb mit einem Compiler erstellten DLL nachzuvollziehen?
//EDIT
Mit dieser Methode kann man übrigens ECHTES Multitasking (eher Multiprocessing) realisieren!
Statt in einem Prozess mehrere Threads zu erstellen, erstellt man einfach mehrere Prozesse!
Windows sorgt selbstständig dafür, dass verfügbare Prozessorkerne ausgelastet werden. ![]()
Sodele, habe mal ein Beispielscript erstellt.
Die EXE mehrfach starten, es wird je gestarteter GUI ein Zähler hochgezählt.
Diesen Zähler kann man beliebig lange "anhalten", indem man den Rahmen der GUI anfasst.
Jede dieser GUI´s lädt die DLL. Diese wird im Speicher natürlich nur einmal erstellt ! Das ist der Sinn einer Dynamic Link Library
Die GUI´s erhalten von dieser DLL nur den Pointer auf den innerhalb der DLL verwendeten Speicherbereich.
Dieser Speicherbereich kann nun von JEDER GUI beliebig gelesen/beschrieben werden.
Dazu wird an der Position dieses Pointers eine beliebige Struct erstellt. Ich habe einen String erstellt, und auch einen INT, welcher als Reset-Flag dient, um die GUI´s zu synchronisieren.
Klickt man nun in einer BELIEBIGEN GUI auf den "Reset/Sync"-Button, wird aus dieser GUI im Speicher der DLL das Reset-Flag gesetzt.
Da alle GUI´s permanent den Status des Reset-Flags im Speicher der DLL abfragen, wird im Falle eines Resets IN JEDER DER GUI´s darauf reagiert und der Zähler auf Null gesetzt.
Interprozesskommunikation! ![]()
Eins ist noch interessant, wenn man den Speicherbereich innerhalb der DLL vergößert, findet irgendwann Avira Antivir in der DLL den Packer.GEN
Wie gesagt, ab einer betimmten Anzahl Nullen in der Datei werden von den Scannern Viren gefunden, weiß jemand den Grund?
//EDIT
Man sollte noch erwähnen, dass die DLL nichts weiter macht, als einen Speicherbereich zu reservieren. Sämtliche Aufteilungen bzw. Strukturen finden alleine im AutoIt-Script statt. So kann man nun Texte, oder Variablen oder Bilder oder wasauchimmer an andere Programme übergeben.
//EDIT2
Script um das "Reset" deutlicher zu machen, compilieren, mehrfach starten...
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;#AutoIt3Wrapper_UseUpx=n
;#AutoIt3Wrapper_usex64=n
$x = Random(1, @DesktopWidth - 500) ;zufällige Position der GUI
$y = Random(1, @DesktopHeight - 150)
$gui = GUICreate("Shared Mem Test, bitte Programm mehrfach starten!", 500, 150, $x, $y);GUI erstellen
$label = GUICtrlCreateLabel("", 20, 20, 100, 30) ;Label
$button = GUICtrlCreateButton("Reset/Sync", 20, 100);Button
GUISetState() ;GUI aktivieren
$dll = DllOpen("sharedmem.dll") ;dll laden
$ptr = DllCall($dll, "dword", "GetPointer") ;den Pointer zum shared memory zurückgeben
$struct = DllStructCreate("char[8];int", $ptr[0]);Struct an dieser Speicherposition erstellen, string und reset-flag
DllStructSetData($struct, 1, "AutoIt") ;Daten schreiben
$i = 0 ;zähler, welcher in allen GUI´s GLEICHZEITIG resettet wird
$t = TimerInit()
While 1 ;endlosschleife
$msg = GUIGetMsg() ;event?
If $msg = -3 Then ExitLoop ;wenn GUI geschlossen, dann ende
If $msg = $button Then ;wenn button, dann resetten
DllStructSetData($struct, 2, 1) ;reset-flag setzen
DllStructSetData($struct, 1, "RESET") ;Text setzen
EndIf
If TimerDiff($t) > 100 Then ;alle 100 Millisekunden die Structinhalte anzeigen
$t = TimerInit() ;Timer starten
If DllStructGetData($struct, 2) = 1 Then ;wenn in irgendeiner GUI der Resetbutton gedrückt wurde
$i = 0 ;zähler nullen
GUICtrlSetData($label, DllStructGetData($struct, 1) & " " & DllStructGetData($struct, 2) & " " & $i);Structinhalte anzeigen
Sleep(1000) ; reset-flag zeigen
DllStructSetData($struct, 2, 0) ;reset-flag zurücksetzen
DllStructSetData($struct, 1, "AutoIt") ;Text zurücksetzen
EndIf
$i = $i + 1 ;zahler erhöhen
GUICtrlSetData($label, DllStructGetData($struct, 1) & " " & DllStructGetData($struct, 2) & " " & $i);Structinhalte anzeigen
EndIf
WEnd
s. EDIT...so ist das, wenn man Threads schreibt/editiert, und erst nach Stunden auf den "abschicken" Button drückt^^
Die DLL an sich wird imho total einfach, es wird nur ein Speicherbereich von 1MB reserviert.
Der Aufruf der Funktion gibt einfach nur einen Pointer auf eben diesen Speicherbereich zurück.
In diesen Speicher kann nun jedes Programm beliebig Daten einschreiben bzw. auslesen. So die Theorie^^
Naja, vielleicht mache ich sogar 2 Funktionen, eine zum Schreiben, die andere zum Lesen. Usability ftw! Ich setz mich mal dran....
//EDIT
naja, fast hätte ich es mir gedacht, klappt so nicht.
Man kann nicht von "außerhalb" auf innerhalb der DLL reservierten Speicher zugreifen.
Hab eine dll erstellt
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32ax.inc' ;includes
[/autoit] [autoit][/autoit] [autoit];einzubindende Librarys
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'
;************Hier die in der DLL verwendeten Funktionen für den Export eintragen
section '.edata' export data readable writable
export 'GETPOINTER.DLL',\ ;Dateiname, Zeilentrenner ist ,\
GetPointer,'GetPointer' ;Funktion
;weitere Sektionen je nach Anforderung der Funktionen
section '.data' data readable writeable
_mem dd 10000 dup 0 ;10 Kb Speicher
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit];section für die Funktionen
section '.code' code readable executable
;DllEntryPoint wird beim Laden der DLL aufgerufen
;um "bombensicheres" Errorhandling zu haben, Funktion anpassen!
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
mov eax,TRUE ;hart aber herzlich^^
ret
endp
;******************Ab hier fangen die Benutzer-Funktionen an **********
[/autoit] [autoit][/autoit] [autoit]proc GetPointer
;ab hier folgt der Code, wie er z.B. von AssembleIt verarbeitet wird
use32
mov eax,_mem ;Startadresse variable
ret
endp
[/autoit] [autoit][/autoit] [autoit]section '.reloc' fixups data discardable
[/autoit]welche auch einwandfrei funktioniert, sie gibt den Pointer auf die Variable _mem zurück.
Allerdings kann man per dllstructcreate(byte[1000],$pointer) nicht auf diesen Speicher zugreifen. ![]()
Umgekehrt funktionierts aber, man könnte der DLL einen Wert übergeben welcher im Speicher der DLL abgelegt wird, die Frage ist, ob von einem 2. Script dieser Speicher gelesen werden kann!
$gui = GUICreate("")
$label = GUICtrlCreateLabel("", 10, 10, 100, 30)
GUISetState()
$struct = DllStructCreate("char[100]")
$ptr = Int(DllStructGetPtr($struct))
$dll = DllOpen("getpointer.dll")
$string = "AutoIt"
$i = 0
$t = TimerInit()
While 1
$msg = GUIGetMsg()
If $msg = -3 Then ExitLoop
If TimerDiff($t) > 1000 Then
$t = TimerInit()
$i = $i + 1
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $i = ' & $i & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$string="AutoIt " & $i
$ret = DllCall($dll, "dword", "VarIn", "str", $string, "int", StringLen($string))
$ret = DllCall($dll, "dword", "VarOut", "ptr", $ptr, "int", DllStructGetSize($struct))
GUICtrlSetData($label, DllStructGetData($struct, 1))
EndIf
WEnd
DLL dazu
; DLL creation example
;
;1) Funktion erstellen in der section .text
; proc Funktionsname
; AssemblerCode....wie er in AutoIt lauffähig ist... hierhinkopieren
; endp
;
;2) In die section .edata den Funktionsnamen eintragen:
;export 'DLLNAME.DLL',\ ;Name der DLL-Datei
;Funktionsname1,'Funktionsname1',\ ;Funktionsnamen
;Funktionsname2,'Funktionsname2'
;
;3) *.asm-datei mit wfasm.exe oder fasm.exe compilieren (in FASMW.EXE laden und CTRL+F9 drücken)
;
;Aufruf aus AutoIt mit
;$ret=dllcall("dllname.dll","RückgabeTYP","Funktionsname","TYP",$parameter1)
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32ax.inc' ;includes
;************Hier die in der DLL verwendeten Funktionen für den Export eintragen
section '.edata' export data readable
export 'GETPOINTER.DLL',\ ;Dateiname, Zeilentrenner ist ,\
VarIn,'VarIn',\ ;Funktion
VarOut,'VarOut' ;Funktion
;weitere Sektionen je nach Anforderung der Funktionen
section '.data' data readable writable
_mem dd 10000 dup 0 ;10 Kb Speicher
;section für die Funktionen
section '.code' code readable executable
;DllEntryPoint wird beim Laden der DLL aufgerufen
;um "bombensicheres" Errorhandling zu haben, Funktion anpassen!
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
mov eax,TRUE ;hart aber herzlich^^
ret
endp
;******************Ab hier fangen die Benutzer-Funktionen an **********
proc VarIn
;ab hier folgt der Code, wie er z.B. von AssembleIt verarbeitet wird
use32
mov esi,[esp+4] ;Startadresse variable
mov ecx,[esp+8] ;länge
mov eax,ecx
mov edi,_mem ;DLL Speicher
rep movsb ;alle bytes von quelle nach ziel kopieren
ret 8
endp
proc VarOut
mov edi,[esp+4] ;Startadresse variable
mov ecx,[esp+8] ;länge
mov esi,_mem ;DLL Speicher
mov eax,edi
rep movsb ;alle bytes von quelle nach ziel kopieren
ret 8
endp
section '.reloc' fixups data discardable
Alles anzeigen
In einem Script( compiliert) gestartet, funktioniert das einwandfrei. Man kann dieses Script laufen lassen und ein weiteres starten, in dem die Zeile mit dem VarIN-Call auskommentiert ist.
Leider wird, wenn man die DLL aus einem weiteren Script anspricht, der Speicher nicht Global angesprochen...werde da wohl nochmal etwas nachhaken müssen!
Funzt nicht...Speicher innerhalb der DLL wird geschützt. Um da ranzukommen, verwendet man die Methode per _WinAPI_ReadProcessMemory(), das geht aber einfacher, s.o.
Hi,
habe mir das mit der DLL durch den Kopf gehen lassen.
Vorteil wäre, beliebig viele Programme auf ein und denselben Speicherbereich zugreifen lassen zu können.
Dazu müsste man imho nur einen Speicherbereich reservieren, die Struktur, also die Definition von Variablen, Konstanten usw. könnte man, ohne die Dll zu verändern, vom jeweiligen Programm aus definieren!
Sozusagen eine universell verwendbare Dll zum beliebigen Datenaustausch.
Bald ist ja Wochenende ![]()
Hi,
ein Schaltbild wäre jetzt nicht schlecht^^. Eine einfache Handzeichnung abfotografiert reicht auch, dann merkt man auch ob die Handy-Kamera etwas taugt
Ich kann mir zwar vorstellen was du machen möchtest, die Schaltung selbst ist mir aber nicht klar.
Welche Meßgeräte hast du zur Verfügung? Ein Billigst-Digitalmultimeter vom Ramschtisch reicht idR völlig aus. Damit kann man wenigstens mal die Potenziale und Spannungen messen.
Wenn du Schalter 1+2 abschaltest, funktionieren dann 3+4 ?
Es könnte, je nach verwendeten Bauteilen, der Strom nicht immer so fließen, wie man sich das vorstellt.
Je nach Schaltung entstehen ggf. durch parallel geschaltete Widerstände völlig andere Voraussetzungen.
Dann muss man unter Zuhilfenahme von bspw. Dioden den Strom "zwingen" bestimmte Wege zu nehmen / nicht zu nehmen.
A propos Strom und Spannung. Ich habe nicht nachgeschaut, welche Leistungen der RasPi an den Pins überhaupt zur Verfügung stellt. Es wäre also ggf. sinnvoll, für die Schaltung eine externe Spannungsversorgung ( Steckernetzteil / Batterien / Akkus) zu verwenden, und den RasPi nur die Eingänge der Transistoren schalten zu lassen.
// EDIT
Radio aus Hosentaschenbauteilen...
Da könnte ich jetzt einen vom Pferd erzählen, aber wie u.a. HIER gezeigt, reichen ein abgestimmter Schwingkreis (bei bestehendem Kondensator wickelt man sich die passende Spule für die benötigte Frequenz) , ein langer (Länge abhängig von der Frequenz^^ ) Draht als Antenne, und ein Piezo-Lautsprecher.
Je nach Länge der Antenne reicht die damit "eingefangene" Leistung aus, um OHNE zusätzliche Stromquelle Radio zu hören!
Mit ner Batterie und einem Transistor (darum heisst das Ding seit Jahrzehnten auch Transistorradio
) oder einer Röhre ( Röhrenradio ftw
aber dran denken, die Angie schaltet die Atomkraftwerke ab ) ist man dann in der Lage einen "richtigen" Lautsprecher anzuschließen!
Übrigens dokumentieren die Fotos aus diesem Link richtige Hightech! Die Holzbretter als Platine hab ich mir immer gespart, einfach alle Bauteile aneinandergelötet gab das meistens unförmige "gnubbelige" Schaltungen mit kalten Lötstellen ![]()
ZitatWerden jetzt die Umgebungsvariablen (EnvSet/EnvGet) im Arbeitspeicher gelagert oder auf der HDD?
Die Umgebungsvariablen werden in der Registry gespeichert. Also auf HDD.
Und ob man nun die Registry direkt beschreibt oder "Umgebungsvariablen" benutzt, ist unerheblich, auf die HDD wird definitiv geschrieben.
Die Methode, direkt aus dem Speicherbereich eines Prozesses zu schreiben, berührt die HDD nicht.
Weiterhin bleiben auch keine "Dateileichen" übrig, wenn die Prozesse beendet werden.
ZitatNun ja, dürfte aber nicht so einfach werden.
yupp, unendlich kompliziert^^
Script1 kompilieren und starten
$gui=guicreate("Script1")
$label=GUICtrlCreateLabel("",20,20,200,30)
guisetstate()
$struct = dllstructcreate("dword;char[20]")
$ptr=dllstructgetptr($struct)
filedelete("ptr.txt")
filewrite("ptr.txt",$ptr)
$x=0
[/autoit] [autoit][/autoit] [autoit]while $x<1000*sleep(1000)
$x=$x+1
GUICtrlSetData($label,$x&" AutoIt_"&$x)
dllstructsetdata($struct,1,$x)
dllstructsetdata($struct,2," AutoIt_"&$x)
wend
Dann Script2 starten
#include <WinAPI.au3>
$gui = GUICreate("Script2")
$label = GUICtrlCreateLabel("", 50, 80, 200, 30)
GUISetState()
$struct = DllStructCreate("dword;char[20]")
$ptr = DllStructGetPtr($struct)
$ptr1 = FileRead("ptr.txt")
[/autoit] [autoit][/autoit] [autoit]$pid = WinGetProcess("Script1")
$ph = _WinAPI_OpenProcess(0x0010, False, $PID)
$bytes=0
$x = 0
While $x < 1000 * Sleep(1000)
$x = $x + 1
$a = _WinAPI_ReadProcessMemory($ph, $ptr1, $ptr, 24, $bytes)
$int = DllStructGetData($struct, 1)
$txt = DllStructGetData($struct, 2)
GUICtrlSetData($label, $int & " " & $txt)
WEnd
Entgegen sonstiger Gewohnheiten habe ich keinerlei Kommentare eingefügt. Wer dafür Kommentare braucht, sollte von dieser Art Scripte die Finger lassen!
Wenn dein Programm 1 eine GUI verwendet, könntest du mit Programm 2 die Daten aus einem Control auslesen.
Weiterhin besteht die Möglichkeit eine DllStruct in Programm 1 zu erstellen und mit Daten zu füllen. Den Pointer auf diese Struct an Programm 2 übertragen (einmalig ggf doch auf Platte schreiben) .
Somit kann Programm 2 auf dem Speicherbereich von Programm 1 zugreifen.
Schau mal in den Eigenschaften des Ordners unter "Sicherheit", ob das Verzeichnis überhaupt freigegeben ist.
Scheinbar werden auch bei Windows-Updates ab und zu Sicherheitseinstellungen für bestimmte Pfade neu gesetzt, ohne den User darüber zu informieren! Jedenfalls habe ich das bei einigen meiner privaten Rechner festgestellt.
ZitatUnd das mit dem Datei lesen/schreiben würde ich gleich verwerfen, gibt nur probleme wenn z.B. die Datei bereits erstellt aber noch nicht fertig geschrieben ist...
Kann ich nicht bestätigen. Habe in Produktivumgebung ca. 10-15 Clients, welche in "Datenbank"-Textdateien schreiben und lesen.
Probleme gibts dabei keine, sämtliche Aktionen laufen im Millisekundenbereich ab. Und sollte doch einmal eine Datei gesperrt sein, na dann gibts nen Fehler welcher abgefangen wird und ne Sekunde später ist die Datei wieder "frei".
Die "Probleme" in diesem Zusammenhang entstehen immer dann, wenn derjenige, der die Programme schreibt, nicht weiß was er gerade tut...wie bei anderen Programmen auch.
Dateien Öffnen, irgendwelche Berechnungen durchführen, und dann Dateien schließen ist, wenn die Berechnungen lange dauern, völliger mumpitz.
Fileread() liest die Datei in Millisekunden ein, dann kann man gemütlich Berechnungen durchführen und DANN die Datei wieder schreiben.
Wie gesagt, eine sehr einfache Lösung, wenn man weiss, was man macht....
Naja, soooo schlimm war das auch wieder nicht, obwohl jenseit der "Mauer" wohl doch....bei uns hab ich einfach alte Fernseher geschlachtet, oder ähnlichen Schrott vom Sperrmüll. Wenn die Bauteile das Auslöten mit dem 50-Watt-Eisen überlebt haben, waren sie auch noch gut für Experimente ![]()
Aber du hast Recht! Wenn ich mich noch richtig erinnere, gabs da doch so ne Geschichte mit ner Schottky-Diode, um lahmen Transistoren bissl auf die Sprünge zu helfen...bei der HF-Technik hab ich mich dann ausgeklinkt.
Nen Radio aus Brocken zusammenbauen, die man in der Hosentasche hat, bekomme ich aber auch heute noch hin ![]()
Das lässt den Schluß zu, dass NUR mit Double gerechnet wird, und einfach die 16 (15 bei Integer wg +- ) Stellen dargestellt werden.
Integer wird demnach per Stringtrimright(zahl, Nachkommastellen) ermittelt
Wenn man "Balls" hat, kann man das genau so machen !
Hab nochmal nachgeschaut, stimmt, die 16 signifikanten Stellen entsprechen exakt "double", 52 Bit Mantisse und 11 Bit Exponent.
Zitatne. Der switcht schon vorher. Wirklich interessant.
Auf den ersten Blick ist das eine BCD-Geschichte
Da hat sich einer gedacht, dass sowieso nur 16 Stellen relevant sind, egal ob Integer oder Float
.
Bin mal gespannt was passiert, wenn sich das 128-Bit-Format rumspricht ![]()
Das finde ich interessanter^^
[autoit]For $i = 1 To 64
$iVal = 2 ^ $i
ConsoleWrite($i & " " & VarGetType($iVal) & " = " & $iVal & @CRLF)
next
Glücklichen Herzwunsch und alles Gute!!!
In 9 Jahren bist du erst halb so alt wie ich dann bin ![]()
BugFix , braucht es imho nicht...
Angenommen, er möchte am Ausgang 12V ( ist Uc im geschalteten Zustand) schalten.
lt. Datenblatt ist Ic=100mA . Wenn Transistor "durchgeschaltet", ist Rc=Uc/Ic=12V/0,1A=120Ohm. Soviel zum Rc.
Schaltstrom Ib=2mA, Vbe=0,7V, Eingangsspannung 3,3V
Gesucht Rb
Ub=3,3V-0,7V=2,6V
Rb=Ub/Ib=2,6V/2mA=1,3kOhm
Sämtlichen "Dreck" an Kleinstspannungen- und Strömen rund um den Transistor kann man bei Gleichstrom unter den Tisch kehren, der wird sowieso durch Temperaturunterschiede und durch die Qualität der Bauteile "aufgefressen".