Auf die LinkedList einer externen DLL zugreifen?

Anfängerfragen zum Programmieren mit PureBasic.
Glow2k9
Beiträge: 11
Registriert: 09.03.2010 14:45

Auf die LinkedList einer externen DLL zugreifen?

Beitrag von Glow2k9 »

Hallo,

ich stehe hier gerade vor einem mittelgroßen Problem und weiss nicht weiter. Folgendes Szenario:

Ich habe eine DLL mit einer exportierten Prozedur. Diese Prozedur erwartet als Parameter eine Datei. Mit der Datei werden dann allerlei Dinge gemacht und, und die Ergebnisse in einer LinkedList gespeichert.
Nun möchte ich von meinem Hauptprogramm aus die DLL laden, die Prozedur mit einer Datei als Parameter aufrufen und dann die LinkedList erhalten um die Inhalte weiterzuverarbeiten.

Zur Veranschaulichung ein bisschen Code, der so natürlich nicht funktioniert weil ich ja nicht weiss wies geht :P

DLL:

Code: Alles auswählen

Structure Daten
  DateiVersion.l
  DateiGröße.l
  DateiErsteZeile.s
EndStructure

Global NewList MeineDatei.Daten()

ProcedureDLL LeseDatei(PfadzurDatei.s)
  MeineDate()\DateiVersion = Mach irgendwas um den Wert zu erhalten
  MeineDate()\DateiGröße = Mach irgendwas um den Wert zu erhalten
  MeineDate()\DateiErsteZeile = Mach irgendwas um den Wert zu erhalten

  ProcedureReturn @MeineDatei()
EndProcedure
Programm:

Code: Alles auswählen

DLLHandle = LoadLibrary_("MeineDLL.dll")

if DLLHandle 
  Prototype _LeseDatei(PfadzurDatei.s)
  Global LeseDatei._LeseDatei = GetProcAddress_(DLLHandle, "LeseDatei")

  HierSollteMeinPointerSein = LeseDatei("C:\MeineDatei.txt")
endif
So, ich hoffe es wird ungefähr deutlich was ich meine. Ich würde jetzt erwarten, dass "HierSollteMeinPointerSein" jetzt ebenfalls die LinkedList beinhaltet, und ich auch die einzelnen Elemente zugreifen kann.

Kann mir vieleicht jemand weiterhelfen? Auch Tips sind schon gut, nehme alles was ihr habt.

Gruß,
Glow
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: Auf die LinkedList einer externen DLL zugreifen?

Beitrag von ts-soft »

Mit einer LinkList kann das nicht funktionieren. Nimm ein Array und FixStrings.
Arraygrösse ByRef zurückgeben und Pointer als Ergebnis.
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
Glow2k9
Beiträge: 11
Registriert: 09.03.2010 14:45

Re: Auf die LinkedList einer externen DLL zugreifen?

Beitrag von Glow2k9 »

Hoi,

zuerstmal Danke für die Antwort. Wenn LinkedLists nicht gehen, gehen vermutlich auch strukturierte (mehrdimensionale) Arrays nicht? Ich werde es jetzt erstmal mit einem eindimensionalen probieren. Gefällt mir dann zwar nicht so gut, aber naja.

Edit: Ich bemerke grad, dass normale Arrays nicht wirklich funktionieren würden. Es kann ja durchaus vorkommen, dass manche Informationen nicht vorhanden sind. Würde ich jetzt einfach ein paar Abfragen haben, und die jeweiligen Ergebnisse (wenn keins vorhanden ist halt einen leeren String) in das Array stopen würde, dann würde das ggf. gehen.
Die Informationen können bei mir allerdings "durcheinander" ankommen. Es ist z.B nicht immer gesagt, dass das erste Ergebniss die DateiVersion wäre im Beispiel oben, es kann genausogut was anderes sein :/

Gruß,
Glow
Glow2k9
Beiträge: 11
Registriert: 09.03.2010 14:45

Re: Auf die LinkedList einer externen DLL zugreifen?

Beitrag von Glow2k9 »

Ha, ich hatte die Erleuchtung! Es funktioniert einwandfrei mit LinkedLists, nur hatte ich einen kleinen Denkfehler. Die Struktur muss natürlich sowohl DLL als auch EXE bekannt sein, und man sollte wissen wie man den pointer den die DLL liefert auch mit der Struktur benutzt ^^

Für diejenigen die es Interessiert, und falls die Nachwelt mal vor einem ähnlichen Problem steht, hier die Lösung (anhand meines Beispiels):

IncludeFile structure.pb

Code: Alles auswählen

Structure Daten
  DateiVersion.l
  DateiGröße.l
  DateiErsteZeile.s
EndStructure
DLL:

Code: Alles auswählen

IncludeFile "structure.pb"

Global NewList MeineDatei.Daten()

ProcedureDLL LeseDatei(PfadzurDatei.s)
  MeineDatei()\DateiVersion = Mach irgendwas um den Wert zu erhalten
  MeineDatei()\DateiGröße = Mach irgendwas um den Wert zu erhalten
  MeineDatei()\DateiErsteZeile = Mach irgendwas um den Wert zu erhalten

  ProcedureReturn @MeineDatei()
EndProcedure
EXE:

Code: Alles auswählen

IncludeFile "structure.pb"

DLLHandle = LoadLibrary_("MeineDLL.dll")

if DLLHandle
  Prototype _LeseDatei(PfadzurDatei.s)
  Global LeseDatei._LeseDatei = GetProcAddress_(DLLHandle, "LeseDatei")

  *MeinPointer.Daten = LeseDatei("C:\MeineDatei.txt")

  Debug *MeinPointer\DateiVersion
  Debug *MeinPointer\DateiGröße
  Debug *MeinPointer\DateiErsteZeile

endif
So bleiben alle Typen erhalten, und alle sind glücklich - vor allem ich :>

Gruß,
Glow
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: Auf die LinkedList einer externen DLL zugreifen?

Beitrag von ts-soft »

Ein Array, strukturiert oder mehrdimensional halte ich trotz allem für sicherer, weil nur bei einem Array
garantiert ist, das die Daten hintereinander im Speicher stehen. Auch Fixstrings sind sicherer, da ansonsten
ja nur der Pointer in der LinkList bzw. dem Array stehen.

Viel schlimmer ist aber, Du verbaust Dir den Weg zu einer späteren Unicode-Version durch Nutzung der
API zum laden der DLL. GetProcAddress_ erwartet den Funktionsnamen in jedem Falle in ASCII.
Also besser OpenLibrary und GetFunction nutzen, zumal die API ja keinerlei Vorteile, sondern eigentlich
nur Nachteile bietet.

Gruß
Thomas
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
Glow2k9
Beiträge: 11
Registriert: 09.03.2010 14:45

Re: Auf die LinkedList einer externen DLL zugreifen?

Beitrag von Glow2k9 »

Hi, danke für den Einwurf. Bezüglich der Sicherheit bin ich da unsicher (:D). Man hat ja direkte Pointer zu der einzelnen Elementen der Struktur. Selbst wenn einzelne Elemente nicht geüllt werden, bekommt man ja auf Abruf den "default" zurück, also ein Leerstring, eine "0" oder "0.0" usw. In wie fern ist das unsicherer?

Wegen dem GetProcAddress: Ich habe ja geschrieben, dass die nur ein Beispiel ist. Es diente lediglich zur Veranschaulichung des Problems mit den LinkedLists. Dennoch, frage ich mich ob das überhaupt relevant ist. Funktionsnamen müssen doch ohnehin in ASCII sein? VisualStudio meckert nach meinen Informationen zumindest rum wenn man Funktionsnamen mit UniCode Zeichen benutzen will, von daher ist es ja "egal" ob GetProcAddress auch nur ASCII kann.

Worüber man sicherlich streiten kann ist die Performace. Da die bei meinem Project allerdings nur eine sehr untergeordnete Rolle spielt bei dieser Funktion, wiegt der Vorteil, dass die Variablentypen erhalten bleiben deutlich mehr. Man erspart sich halt eine ganze Menge Konvertierungen (je nach Menge der Struktur Elemente).

Gruß,
Glow
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: Auf die LinkedList einer externen DLL zugreifen?

Beitrag von ts-soft »

Glow2k9 hat geschrieben:Dennoch, frage ich mich ob das überhaupt relevant ist. Funktionsnamen müssen doch ohnehin in ASCII sein? VisualStudio meckert nach meinen Informationen zumindest rum wenn man Funktionsnamen mit UniCode Zeichen benutzen will, von daher ist es ja "egal" ob GetProcAddress auch nur ASCII kann.
Naja, wenn in den Compileroptionen Unicode gewählt wurde, wird auch Unicode an GetProcAdress_
übergeben, wird also nicht funktionieren. Du müsstest also selber den Funktionsnamen in ASCII in einen
Speicher poken. Das kannst Du Dir sparen, wenn Du die nativen PB Funktionen nutzt.
Auch wenn Du kein Unicode nutzen möchtest, sollte man sich alle Möglichkeiten offen halten. Vielleicht
ändert sich das doch, oder Du möchtest eine Procedure Deines Programmes woanders nutzen und fängst
dann an, es umzuschreiben.

Ich achte immer drauf, das mein Code Ascii/Unicode, x86 / x64 kompatible und möglichst Crossplattform
ist, egal ob das gerade benötigt wird oder nicht.
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
Antworten