Speicherbereich mit DLL ansprechen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Speicherbereich mit DLL ansprechen

Beitrag von ProgOldie »

Hallo,
ich möchte von einem anderen Programm aus über eine DLL einen Speicherbereich reservieren und in ihm Daten ablegen, die dann von PB nach einem erneuten Aufruf aus dem Fremdprogramm weiterverarbeitet werden sollen.
Hintergrund: Die Daten sollen extrem schnell und unter Nutzung der Möglichkeiten von PB dargestellt werden können. Ein Beispiel wären astronomische Daten, die einmalig in den Speicherbereich geschrieben werden. Anschließend werden sie schnell und wiederholt ausgelesen, um dann visualisiert zu werden.
Zur Vereinfachung gehe ich davon aus, dass es sich um LongInt Daten handelt.

Leider fehlen mir reihenweise Kenntnisse über DLLs. Trotzdem ein kleiner Versuch:

Code: Alles auswählen

ProcedureDLL reserveMem(Mem.q)
  ; reserviert einen Speicherbereich der Größe Mem und reicht dessen Startadresse zurück
  *MemStart = AllocateMemory(Mem.q)
  If Not(*MemStart)
    MessageRequester("... gescheitert","Speichereinrichtung")
  EndIf
EndProcedure

ProcedureDLL saveMem(StoreNr.L,Wert.L)
  ;Schreibt den Wert mit der Nummer StoreNr in den Speicherbereich
  PokeL(*MemStart+(StoreNr-1)*4,Wert)
EndProcedure
Meine Probleme (u.a.):
a) ist die Idee grundsätzlich überhaupt realisierbar?
b) Wie reicht man aus der DLL die Startadresse des Speicherbereiches zurück?
c) Wie berücksichtigt man, dass es für 32-bit und 64-Bit funktioniert?

Dank schon 'mal vorab.
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Speicherbereich mit DLL ansprechen

Beitrag von NicTheQuick »

Du definierst als Rückgabewert Integer und gibt's '*MemStart' einfach zurück. Der Integer passt sich automatisch an 32- oder 64-Bit-System an.

Code: Alles auswählen

ProcedureDLL.i reserveMem(Mem.q)
	; reserviert einen Speicherbereich der Größe Mem und reicht dessen Startadresse zurück
	
	Protected *MemStart = AllocateMemory(Mem.q)
	
	If Not (*MemStart)
		MessageRequester("... gescheitert", "Speichereinrichtung")
	EndIf
	
	ProcedureReturn *MemStart
EndProcedure
Damit du '*MemStart' auch in 'saveMem()' nutzen kannst, musst du '*MemStart' natürlich global machen.
Außerdem würde ich allgemein Integer (.i) nutzen und keine Longs (.l).
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Re: Speicherbereich mit DLL ansprechen

Beitrag von ProgOldie »

Hi Nick, very quick!
Könntest du noch 'mal einen Blick auf die folgende korrigierte Fassung werfen? Ich habe Sorge, dass ich mir bei einem Fehler mit AllocateMemory() das System zerschieße.

Code: Alles auswählen

Global *MemStart

ProcedureDLL.i reserveMem(Mem.q)
  ; reserviert einen(!) Speicherbereich der Größe Mem und reicht dessen Startadresse zurück 
  ; Wenn 0 zurückgereicht wird: Gescheitert
  If *MemStart    ;gibt einen ggf. zuvor reservierten Speicherbereich frei
    FreeMemory(*MemStart) 
  EndIf
  Protected *MemStart = AllocateMemory(Mem.q) 
  ProcedureReturn *MemStart
EndProcedure

ProcedureDLL saveMem(StoreNr.i,Wert.i)
  PokeI(*MemStart+(StoreNr-1)*4,Wert)
EndProcedure
O.K. so?
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Benutzeravatar
_JON_
Beiträge: 389
Registriert: 30.03.2010 15:24

Re: Speicherbereich mit DLL ansprechen

Beitrag von _JON_ »

Mem.q lass da mal das ".q" weg macht keinen Sinn.
Wenn schon den schon ".i", aber integer ist Standard, muss also nicht geschrieben werden.

PokeI(*MemStart+(StoreNr-1)*4,Wert)

Ich weiß zwar nicht was Du hier machst aber PokeI schreibt unter x64 8 Bytes
vielleicht wäre es so besser:

PokeI(*MemStart+(StoreNr-1)*SizeOf(Integer),Wert)
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Speicherbereich mit DLL ansprechen

Beitrag von ts-soft »

*MemStart ist global, also kein Protected vor dem allokieren, weil das wären dann 2 verschiedene Variablen, wobei eine
nur in der Procedur gültigkeit hätte!

Und was soll der quad bei mem? Anzahl Bytes in Integer!

Gruß
Thomas

//edit zu spät, aber das Global ist ja noch wichtig!
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Re: Speicherbereich mit DLL ansprechen

Beitrag von ProgOldie »

Dank allen für die Korrekturen, die ich jetzt 'mal zusammengefasst habe. Zusätzlich habe ich noch eine Sicherung eingefügt, dass der Integerwert auch wirklich in den Bereich passt.

Code: Alles auswählen

Global *MemStart

ProcedureDLL.i reserveMem(Mem.i)
  ; reserviert einen(!) Speicherbereich der Größe Mem und reicht dessen Startadresse zurück 
  ; Wenn 0 zurückgereicht wird: Gescheitert
  If *MemStart    ;gibt einen ggf. zuvor reservierten Speicherbereich frei
    FreeMemory(*MemStart) 
  EndIf
  *MemStart = AllocateMemory(Mem) 
  ProcedureReturn *MemStart
EndProcedure

ProcedureDLL saveMem(StoreNr.i,Wert.i)
  ;Im Bereich stehen fortlaufend Integer-Werte;
  ;Der Integerwert mit der Nummer StoreNr erhält nun 'Wert'.
  If Int(MemorySize(*MemStart) / SizeOf(Integer)) > StoreNr  ; Dieser Integerwert passt hinein
    PokeI(*MemStart+(StoreNr-1)*SizeOf(Integer),Wert)
  EndIf
EndProcedure
Nun ist es hoffentlich richtig!
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Antworten