![]() |
Re: Neustrukturierung einer DLL
Der Nachteil einer Enumeration ist das bei Delphi nur ein Byte fuer den Typ genommen wird, waehrend C 4 Bytes nimmt. Bleibt man bei einfachen Konstanten und nimmt Integer als Typ fuer den Parameter so erspart man sich die Probleme mit der Groesse des Typs.
Es heisst uebrigens in englisch nicht "type" sondern "kind" (Art). Das ist ein beliebter Fehler bei der Namensgebung.
Delphi-Quellcode:
const
BASSVISKIND_SONIQUE = 1; BASSVISKIND_WINAMP = 2; BASSVISKIND_WMP = 3; type BASSVIS_KIND_T = Integer;
Code:
Zur Abstraktion sollte man uebrigens alles mit eigenen Typen versehen. Das bewirkt das die Programme in allen Sprachen aehnlicher aussehen. Die jeweilige Header-Datei mappt dann die Typen auf passende Basistypen.
#define BASSVIS_SONIQUE 1
#define BASSVIS_WINAMP 2 #define BASSVIS_WMP 3 typedef int BASSVIS_KIND_T; So jetzt zu der Idee des Supersets. Die APIs haben nicht so viel Ueberschneidung. Das sollte man erst mal aufarbeiten. Ein Beispiel waere dies:
Delphi-Quellcode:
Das ist jetzt nur die grobe Richtung in der es gehen soll. Das API muss noch deutlich vereinheitlicht werden.
procedure BASSVIS_Play(Kind: BASSVIS_KIND_T; Handle: HVIS); stdcall;
begin case Kind of BASSVISKIND_SONIQUE: { nichts zu tun }; BASSVIS_WINAMP: BASS_WINAMPVIS_Play(Handle); BASSVIS_WMP: BASS_WMPVIS_Play; end; end; |
Re: Neustrukturierung einer DLL
Zitat:
Da ich dann über ein untermenü verfüge und bei case anweisungen die deklarierte Type als vergleich nehmen kann. Zitat:
Mein hauptproblem kurz erklärt Sorry Beispiel VB_NET habe da mal auf die schnelle was zusammen gezimmert da ich mich hier besser auskenne als in Delphi.
Code:
Wenn ich hier die DLL aufrufe
Public Sub New(ByVal PluginPath As String, ByVal DefaultVisualizationType As VisualsType, ByVal WindowHandle As Int32, ByRef Container As Windows.Forms.Control, ByVal StreamOrMixerHandle As Int32)
If m_WindowHandle = 0 Then 'Store the type of visualization being performed m_VisType = DefaultVisualizationType 'Set the container object for the visuals m_VisContainer = Container 'Store the window handle m_WindowHandle = WindowHandle 'Get the Device Context for the control m_ContainerhDC = GetWindowDC(m_VisContainer.Handle) 'Get the device handle for the control Try m_VisContainerHandle = m_VisContainer.Handle Catch m_VisContainerHandle = 0 End Try 'Store the stream handle m_BassStream = StreamOrMixerHandle 'Set the default plugin path m_PluginPath = PluginPath 'Load the bass vis plugin Call LoadBassVis() Else Throw New Exception("This object already has a window applied, destroy this object instance and create a new one.") End If End Sub
Code:
dann erstellt m_VisWrapper eine neue Instanz und die eigenschaften der DLL können dann über m_VisWrapper
'Create the new bass wrapper if playback started
m_VisWrapper = New BASSVis_Wrapper.BassVisWrapper(Application.StartupPath & "\plugins\", m_CurrentType, Me.Handle, pbVisuals, m_Mixer) verwaltet werden denke du verstehst was ich meine. Die DLL wird dann quasi als verweis in das Projekt mit eingebunden. Ist das unter Delphi möglich? Oder wie am besten vorgehen das ich beim wechsel eines VisType jedesmal eine neue Instanz erzeuge. Da komme ich unter Delphi irgendwie nicht mit klar. LoadBassVis macht dann genau das was du unter SuperSet verstehst.
Code:
Mir geht es um das Problem der Initialisierung und der automatischen zerstörung der Instanz
Private Sub LoadBassVis()
'get hInstance from Applications handle m_VisWindowHandle = BassVis.GetWindowLongPtr(m_WindowHandle, Un4seen.Bass.AddOn.Vis.GWLIndex.GWL_HINSTANCE) If m_VisType = VisualsType.WinAMP Then 'Init BassVis BassVis.BASS_WINAMPVIS_Init(m_VisWindowHandle, m_WindowHandle) ElseIf m_VisType = VisualsType.WindowsMedia Then 'Init BassVis BassVis.BASS_WMPVIS_Init(m_VisWindowHandle, m_WindowHandle) End If End Sub wenn der VisTyp geändert wird. gruss und danke für die Infos Emil |
Re: Neustrukturierung einer DLL
Die Frage ist ob der Benutzer alle drei APIs parallel verwenden will oder immer nur eines. Will er nur eines der APIs verwenden, dann kann man ja eine Initialiiserungsfunktion und eine Finalisierungsfunktion einfuehren und spart sich den Parameter.
BASSVIS_Initialize(Kind) und BASSVIS_Finalize(Kind). Kind hebt man sich in einer globalen Variablen in der DLL auf und macht die Switches anhand dieser Variablen anstatt des Parameters. Die beiden Funktionen kuemmern sich auch um die Initialisierung und Finalisierung des jeweiligen APIs so das man diese nacheinander verwenden kann. Mit dem VB mus ich mich noch beschaeftigen. |
Re: Neustrukturierung einer DLL
Zitat:
Beim start wird eine neue Instanz von BassVis erstellt ohne irgendeinen Typ auszuführen. Bei der auswahl eines Types werden die Plugins eingeladen abhängig vom Typ Beim wechsel das gleiche nur das die alte Instanz dann zerstört werden soll was ich innerhalb bassvis regeln muss sobald ein neuer typ initialisiert wird. Dies sollte aber automatisch geschehen classen abhängig. Die VisTypen sollen also on the Fly geändert werden können ohne das ich hunderte API's der verschiedenen Arten außerhalb BassVis verwenden muss. Wenn er nur eins verwenden will (auch auf dieser art möglich) brauchte ich die API nicht umschreiben Da aber drei verschiedene Typen nutzbar sind muss ich davon ausgehen das auch alle verwendet werden. gruss Emil |
Re: Neustrukturierung einer DLL
Mal ans eingemachte
Mit dieser funktion Initialisiere ich zum beispiel Winamp-Plugins
Delphi-Quellcode:
function BASS_WINAMPVIS_Init(AppHandle: DWORD; WinHandle: DWORD): boolean; stdcall;
begin try ApplicationHandle := AppHandle; FormParentHandle := WinHandle; BassVis1 := TBassVis.Create(nil); finally // Nothing end; result := True; BassVisInit := Result; end;
Delphi-Quellcode:
constructor TBASSVis.Create(AOwner: TComponent);
begin inherited Create(AOwner); DecodeChannel := 0; FPlayerMode := plmStandby; FStreamName := ''; FStreamInfo.FileName := nil; FStreamInfo.FileSize := 0; FStreamInfo.SampleRate := 0; FStreamInfo.Pos := 0; FStreamInfo.Len := 0; FStreamInfo.PlaylistFileLength := 0; FStreamInfo.PlaylistPos := 0; ....
Delphi-Quellcode:
Kann ich die INIT Routine so belassen wenn ich zu dieser funktion das Kind addiere?
destructor TBASSVis.Destroy;
Und den Namen BASS_WINAMPVIS_Init nach BASSVIS_Init umbenenne.
Delphi-Quellcode:
theoretisch müßte ja dann bei jeden neuen aufruf von INIT zuerst Destroy ausgelößt werden
function BASSVIS_Init(Kind: BASSVIS_KIND_T; AppHandle: DWORD; WinHandle: DWORD): boolean; stdcall;
das wäre ja dann ein automatisches beenden der classe. In Destroy müßte dann nur das Kind verglichen werden um das vorher aktivierte Plugin zu beenden. Wäre das eine Lösung ? bzw.. welchen Namen könnte man der Function übergeben das es unter allen anderen Sprachen korrekt interpretiert wird. gruss Emil |
Re: Neustrukturierung einer DLL
Warum willst du verhindern, das jemand mehrere unterschiedliche Plugin's gleichzeitig verwendet ?
|
Re: Neustrukturierung einer DLL
Zitat:
Sonique Plugins benötigen im VollScreen fast 80% CPU je nach dem wie hoch der ScreenMode eingestellt ist. Bei Winamp und WMP ist das nicht viel anders. Man sollte daher vermeiden das mehrere Plugins gleichzeitig laufen. Die Anwendung verwendet ja auch noch resourcen und ich will nicht schuld sein das da nachher nix mehr läuft. EDIT: Und ich arbeite schon mit FFTW der Turbo unter den FFT Algorythmen gruss Emil |
Re: Neustrukturierung einer DLL
ok..es gibt ein paar Plugins die wirklich Resourcen fressen. Und Winamp selbst machts auch so,das es das alte Plugin beendet, bevor es das neue startet.
Aber dafür gibts ne einfach Lösung. Gib HVIS nicht nach außen und handle das intern selbst (globale Variable). Dazu noch eine, die dir sagt, welcher Art das aktuell laufende Plugin ist. Damit kannst du dann die Interface-Routinen stark vereinfachen. Für "Create" und "Destroy" brauchst du jeweils nur 1 Funktion. Der wird vom Anwender übergeben, welche Art von Plugin er haben möchte. Alle anderen Funktionen brauchst du auch nur einmal, da du ja dann intern weißt, welcher Plugintyp läuft. Das würde dann fürs Erzeugen z.B. so aussehen:
Delphi-Quellcode:
So kannst du alle Funktionen die notwendig sind, globalisieren.function BASSVIS_INIT(Kind:BASSVIS_KIND_T;AppHandle:Dword;WndHandle:HWND):bool; begin if (GLOBALHVIS <> 0) then BASSVIS_EXIT; //altes Plugin freigeben GlobalKind := Kind; Case Kind of SONIQUE : GLOBALHVIS := BASS_SONIQUEVIS_CreateVis... WINAMP : GLOBALVIS := BASS_WINAMPVIS_ExecuteVis.... WMP : GLOBALVIS := BASS_WMPVIS_ExecuteVis.... end; end; |
Re: Neustrukturierung einer DLL
Wäre eine möglichkeit ;)
Aber ganz so einach ist es nicht. Da beim initialisieren auf keinen Fall ein Plugin ausgeführt werden darf diese ist nur da um default Values einzulesen und die zum Plugin gehörende class(TComponent) zu initialisieren. Habe das mal ansatzweise versucht scheitere aber schon daran wenn das WMP Plugin aufgerufen wird beim beenden der Anwendung Destroy nicht aufgerufen wird. Wenn BASSVis1 aufgerufen wurde und die Anwendung beendet funktioniert das Destroy event (dort springt er rein)
Delphi-Quellcode:
gruss Emil
function BASSVIS_Init(Kind: BASSVIS_KIND_T; AppHandle: HWND; WinHandle: HWND): BOOL; stdcall;
begin try ApplicationHandle := AppHandle; FormParentHandle := WinHandle; if Assigned(BASSVis1)then BASSVis1.Destroy; if Assigned(BASSWMPVis1) then BASSWMPVis1.Destroy; begin case Kind of BASSVISKIND_WINAMP: BassVis1 := TBassVis.Create(nil); BASSVISKIND_SONIQUE: { nichts zu tun }; BASSVISKIND_WMP: BassWMPVis1 := TBassWMPVis.Create(nil); end; end; finally // end; result := True; BassVisInit := Result; end; end. |
Re: Neustrukturierung einer DLL
Was logisch ist, da du nur den Destruktor aufrufst, aber das Objekt (in dem fall TComponent) nicht freigibst.
Delphi-Quellcode:
if Assigned(BASSVis1)then
BASSVis1.free; if Assigned(BASSWMPVis1) then BASSWMPVis1.free; :) BTW...für was brauchst du da eine TComponent-Klasse ? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz