Toon posts:

[VB6-Delphi] Multithreading

Pagina: 1
Acties:
  • 112 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik heb hier een vrij forse VB6 applicatie liggen waarvan een gedeelte van de code eigenlijk beter in een eigen thread terecht kan.
Nou weet ik dat threading in VB6 een no-go is. Het is via allemaal omwegen wel te doen, maar stabiel zal het nooit worden.
Dus ik dacht eraan om een stdcall dll wrapper te maken in delphi als snelle oplossing.

De betreffende code van de VB app stop ik in een COM dll
De stdcall dll maakt een thread en roept daarin het COM object aan
De VB6 app gaat lekker verder en als de thread van de dll klaar is doet ie een callback om de VB6 app op de hoogte te stellen.

Nou weet ik dat het niet de mooiste oplossing is, maar herschrijven is gewoon soms geen optie met grotere applicaties.
Efin, alles lijkt goed te gaan behalve 1 ding:
Als ik bijvoorbeeld in de stdcall dll een Sleep uitvoer van, laten we zeggen, 10 seconden dan werkt alles zoals je zou verwachten.
De VB6 app lijkt niets door te hebben en hij heeft zijn eigen thread lekker vrij.
Maar als ik in de nieuwe thread van de stdcall dll het COM object aanroep, dan hangt de VB6 app alsof het in zijn eigen thread gebeurt!

Dingen die ik heb geprobeerd:
In de stdcall dll een sleep uitvoeren, maar daar doet het probleem zich niet voor.
In de stdcall dll een busy loop maken die van alles doet om te kijken of het komt doordat de thread op een of andere manier toch teveel cpy cycles opeist, maar ook daar geen problemen.
In de COM dll een sleep zetten, maar dan hangt de applicatie dus weer.

De thread spawn ik uiteraard in de idle priority class voor deze tests.

Het enige wat ik me zou kunnen bedenken is dat de COM dll ook de VB6 runtime gebruikt en dat het daar ergens misgaat.
Ik heb alleen helaas niet echt veel verstand van al het echte low level gebeuren.
Misschien is er iemand die er wat meer info over heeft?

Verwijderd

Topicstarter
Zit je eerst 2 uur te klooien, besluit je de hulp van anderen in te schakelen, kom je zelf tot de oplossing!
De COM dll was niet gecompiled met 'Apartment threaded' |:(
Dus werd ie overgeerfd door de main thread (applicatie).

Nou ja, misschien helpt het nog iemand in de toekomst, al denk ik van niet...

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Bedenk wel dat je je callback terug moet marshallen naar de calling thread anders krijg je problemen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
Hoe bedoel je precies? De callback is naar een publieke functie in een module.

pseudo code
Visual Basic:
1
2
3
4
5
6
7
Private Sub CallDll
   Call Foo(AddressOf Callback)
End Sub

Public function CallBack(ByVal lpsz As Long, ByVal lRetVal As Long) as Long
  Debug.Print ToBSTR(lpsz), lRetVal
End Sub


Dan in Delphi iets als
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fpCallback:function (pcFoo:PChar;nRet:Interger):Integer;stdcall;

//die assign ik dan zo
function Foo(CallbackAddress:Pointer):Integer;stdcall;
begin
  @fpCallBack:=CallBackAddress;
end;

 //en zo roep ik 'm aan als de thread klaar is (niet vanuit de nieuwe thread zelf)
class procedure TDummyClass.OnThreadDone(Sender: TObject);
begin
  With ( Sender as TThreadFoo) do begin
      if Assigned(fpCallback) then begin
        fpCallback(parameter1,parameter2);
      end;
  end;
end;


Maar da's even uit het blote hoofd....

Moet er dan nog iets gemarshalled worden?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
De VB Callback routine moet aangeroepen worden in dezelfde thread als waarin de VB applicatie draait anders kun je problemen krijgen. Dat is dus dezelfde thread waarin Foo in je voorbeeld wordt aangeroepen.

Als die OnThreadDone in die thread zit heb je niets te vrezen :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.