AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Multithreading DLL

Ein Thema von Aya · begonnen am 29. Okt 2006 · letzter Beitrag vom 29. Okt 2006
Antwort Antwort
Benutzerbild von Aya
Aya

Registriert seit: 24. Jul 2003
Ort: Kassel
138 Beiträge
 
Delphi 6 Professional
 
#1

Multithreading DLL

  Alt 29. Okt 2006, 13:35
Hi,

ich habe ein programm mit DLLs..

Ich habe in Delphi eine DLL geschrieben, welche eine Klasse exportiert, bzw eine funktion welche eine neue instanz der Klasse erstellt.

Das ganze sieht etwa so aus:

Delphi-Quellcode:
TDLLClass = class
public
  function loadImage(filename: PChar): Longword;
end;

function createClass: TDLLClass;
begin
  Result:=TDLLClass.Create;
end;

exports
  createDLL;
die funktion loadImage lädt ein Bild in den speicher (Speicher wird reserviert mit GetMem) und gibt dann einen Pointer auf den Speicherbereich zurück.

Das ganze klappt wunderbar, allerdings nur solange nur ein Thread gleichzeitig läuft.
Wenn ich nun also 2 Threads gleichzeitig laufen lasse welche loadImage aufrufen, schmiert irgendwann (komischerweise nicht sofort, sondern erst nach einiger zeit) das programm ab...

Die Zeit nach der es abschmiert ist immer etwa gleich (ca~ nach 20 Bildern).

Es liegt 100%ig nicht daran das irgendwo auf gleiche variablen zugegriffen wird, denn:
Wenn ich den Code der DLL einfach in das Hauptprogramm kopiere und so den DLL aufruf umgehe, funktioniert es selbst mit 10 Threads fehlerfrei.

Auch wenn ich für jeden Thread eine neue klasse der DLL erstelle funktioniert es nicht... es muß also irgendwo an der schnittstelle zwischen Programm/DLL liegen.

Hat da jemand eine Idee?

Au'revoir,
Aya~
I aim for my endless dreams and I know they will come true!
S: String = #86^)^3^)^4#58#32^(^4^4^0#58#47#47^7^7^7#46^+^/^3^(^)^'^!^9^!#46^$^%;
  Mit Zitat antworten Zitat
Benutzerbild von Aya
Aya

Registriert seit: 24. Jul 2003
Ort: Kassel
138 Beiträge
 
Delphi 6 Professional
 
#2

Re: Multithreading DLL

  Alt 29. Okt 2006, 21:58
Nach langer sucherei und tausenden dingen die ich ausprobiert hab, hat Olli mir diesen Tip gegeben:

System.IsMultiThread:=True;

einfach in EXE + DLL und fertig, klappt

*Olli knuddel*

Aya~
I aim for my endless dreams and I know they will come true!
S: String = #86^)^3^)^4#58#32^(^4^4^0#58#47#47^7^7^7#46^+^/^3^(^)^'^!^9^!#46^$^%;
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#3

Re: Multithreading DLL

  Alt 29. Okt 2006, 23:03
Da war dann noch ein Problem.

Aya hat die MM-Funktionen Delphi-Referenz durchsuchenGetMem() und Delphi-Referenz durchsuchenFreeMem() benutzt um Speicher anzufordern und freizugeben. Allerdings hat er einmal in der DLL angefordert und versucht in der EXE freizugeben. Das sollte man nicht machen.

Man muß sich das so vorstellen, daß es zwei "Instanzen" des MM gibt. Einmal in der DLL und einmal in der EXE. Beide arbeiten unabhängig voneinander und verwalten ihre Speicherblöcke. Während ein Delphi-Referenz durchsuchenCopyMemory() noch problemlos geht, ist das bei Delphi-Referenz durchsuchenFreeMem() und Delphi-Referenz durchsuchenGetMem() nicht mehr gegeben - zwei verschiedene MM-Instanzen bedeuten hier, daß der MM welcher einen Block anfordert diesen auch freigeben muß. Man muß sich den MM wie einen Buchhalter vorstellen. In unserem Fall zwei Buchhalter. Beide führen Buch über die ausgegebenen Speicherblöcke und über die, welche zurückgegeben wurden. Aber sie können nicht miteinander kommunizieren - daher wissen sie nicht von den Speicherblöcken des jeweils anderen oder können gar in dessen "Buchhaltung" eingreifen.

Die beste Methode ist, wenn die DLL ihre eigenen Funktionen mitbringt um Speicher zu allozieren und freizugeben. Dadurch wird die Aufgabe an den "DLL-Buchhalter" delegiert, wenn es denn notwendig ist. Und schwuppdi gibt es keine ungültigen Zeigeroperationen mehr

Alternativ kann man die Heap-Manager-Funktionen ala MSDN-Library durchsuchenLocalAlloc(), MSDN-Library durchsuchenGlobalAlloc(), MSDN-Library durchsuchenHeapAlloc() usw. mit ihren jeweiligen Counterparts benutzen. Der Heap-Manager ist prozess-spezifisch und somit nicht abhängig vom aktuellen Modul.

Kann mir vorstellen andere haben auch diesen Denkfehler, denn Aya ist ja nicht gerade Anfänger - daher mein Kommentar! ...

Nachtrag:
Im Falle von MSDN-Library durchsuchenHeapAlloc() und MSDN-Library durchsuchenHeapFree() gilt die Aussage natürlich nur bei Verwendung von MSDN-Library durchsuchenGetProcessHeap(). Ansonsten könnte man natürlich schon modulspezifische Heaps angeben.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz