![]() |
Procedure Safecall > function?
Ich möchte eine procedure Safecall überschreiben so das ich das ergebnis zurückgeliefert bekomme.
Delphi-Quellcode:
Das Plugin behandelt es so..
IWMPEffects2 = interface(IWMPEffects)
['{695386EC-AA3C-4618-A5E1-DD9A8B987632}'] .... procedure Destroy; safecall; ...
Delphi-Quellcode:
Laut MS..
procedure TVisualization.IWMPEffects2_Destroy;
begin FhwndParent := 0; end; Zitat:
Wie das Interface casten damit es richtig verarbeitet wird? Ich würde es ja so schreiben.
Delphi-Quellcode:
Nur eine procedure erlaubt ja bekanntlich keinen Result Type.
function Destroy(): Bool;
begin result := false; if Assigned(_IWmpEffects2) then if _IWmpEffects2.Destroy = S_OK then result := true end; Zur zeit sieht es so aus..
Delphi-Quellcode:
Aber dann weiss ich nicht ob das Plugin sich zu dieser zeit
function DestroyInterface: Bool;
begin Result := False; // ist ein Visualisierungs-Objekt vorhanden if Assigned(BassWMPVis1.WmpVis) then begin // dann freigeben if Assigned(_IWmpEffects2) then _IWmpEffects2 := nil; if Assigned(_IWmpEffects) then _IWmpEffects := nil; BassWMPVis1.WmpVis := nil; Result := True; end; end; richtig beendet hat. gruss |
AW: Procedure Savecall > function?
Muss nochmal nachfragen vielleicht wurde der Thread übersehen..
Zu Safecall: Safecall erzeugt ja selber den OLE-Error wenn ein COM-Aufruf nicht funktioniert. Kann ich nicht einfach das Interface so deklarieren wie von MS vorgeschrieben also mit Rückgabe der jeweiligen function? Die bei erfolg S_OK wäre. Wie gesagt ich habe im moment das problem mit dem Timing zum beispiel beim Rendern. Wenn ich hier das Renderevent abfragen würde könnte ich darauf reagieren und das Visualizations Plugin hätte genügend zeit seinen RenderThread abzuschließen. Muss dann nur noch schaun ob die Plugins stdcall oder cdecl aktzeptieren. gruss |
AW: Procedure Safecall > function?
Mal anders gefragt:
Woher stammt denn die Delphi-Implementierung des Interfaces? In der Referenz und wenn ich mich recht entsinne im SDK steht die Funktion ja schließlich mit Rückgabewert drin. Deshalb würde ich sagen, dass du am besten die Deklaration aus dem SDK nimmst und selbst so in Delphi umsetzt, dann sollte das funktionieren. |
AW: Procedure Safecall > function?
Delphi-Quellcode:
Das ist das besagte Interface.
{' UNIT WMPEffects.pas
'--------------------------- BassVis API Module ----------------------------- ' BassVis ADD-ON for Bass Audio Library ' Copyright © 2006-2012 BrewIdeas@Emil Weiss, All Rights Reserved ' ' Author(s) of this Unit: Emil Weiss ' '----------------------------------------------------------------------------} unit WMPEffects; interface uses Windows, WMPLib_TLB; const SA_BUFFER_SIZE = 1024; IID_IWMPEffects : TGUID = '{D3984C13-C3CB-48e2-8BE5-5168340B4F35}'; IID_IWMPEffects2 : TGUID = '{695386EC-AA3C-4618-A5E1-DD9A8B987632}'; IID_IWMPMedia: TGUID = '{94D55E95-3FAC-11D3-B155-00C04F79FAA6}'; Type EffectsCapability = (EFFECT_CANGOFULLSCREEN = $00000001, // can the effect go full screen? EFFECT_HASPROPERTYPAGE = $00000002, // does the effect have a property page? EFFECT_VARIABLEFREQSTEP = $00000004, // should effect return frequency data with variable size steps? EFFECT_WINDOWEDONLY = $00000008, EFFECT2_FULLSCREENEXCLUSIVE = $00000010); Type TimedLevel = record frequency : array [0..1, 0..SA_BUFFER_SIZE-1] of byte; waveform : array [0..1, 0..SA_BUFFER_SIZE-1] of byte; state : integer; timeStamp : int64; Rendering : Bool; end; IWMPEffects = interface(IUnknown) ['{D3984C13-C3CB-48e2-8BE5-5168340B4F35}'] // Render using the rectangle on the normalized device context //void Render(ref TimedLevel levels, IntPtr hdc, ref RECT r); procedure Render(var pLevels : TimedLevel; hdc : HDC; var prc : TRect); safecall; // provides the no. channels, sample rate and title of the audio currently playing procedure MediaInfo(lChannelCount : longint; lSampleRate : longint; bstrTitle : WideString); safecall; // called to retrieive the capabilities of the effect (fullscreen? property page?, etc.) procedure GetCapabilities(var pdwCapabilities : DWORD); safecall; // retrieve the display title of the effect procedure GetTitle(var bstrTitle : WideString); safecall; // retrieve the title for a preset procedure GetPresetTitle(nPreset : LongInt; var bstrPresetTitle : WideString); safecall; // retrieve the number of presets this effect supports procedure GetPresetCount(var pnPresetCount : LongInt); safecall; // set / get the current preset procedure SetCurrentPreset(nPreset : LongInt); safecall; procedure GetCurrentPreset(var pnPreset : LongInt); safecall; // display the property page of the effect (if there is one) procedure DisplayPropertyPage(hwndOwner : HWND); safecall; // This method will be called when the effect is to start and stop full screen // rendering (if supported) procedure GoFullscreen(fFullScreen : BOOL); safecall; // This method will get called after a successful call to GoFullScreen to render // the effect. Return failure from this method to signal loss of full screen. procedure RenderFullScreen(var pLevels : TimedLevel); safecall; end; IWMPEffects2 = interface(IWMPEffects) ['{695386EC-AA3C-4618-A5E1-DD9A8B987632}'] // Called by Windows Media Player to provide visualization access to the // core Windows Media Player APIs. procedure SetCore(var pPlayer : IWMPCore); safecall; // Called by Windows Media Player to instantiate a visualization window procedure Create(hwndParent : HWND); safecall; // Called by Windows Media Player to destroy a visualization window // instantiated in the Create method. procedure Destroy; safecall; //Called by Windows Media Player to inform the visualization that a new //media item has been loaded. procedure NotifyNewMedia(var pMedia : IWMPMedia); safecall; // Called by Windows Media Player to pass window messages to a visualization. procedure OnWindowMessage(msg : UINT; WParam : WPARAM; LParam : LPARAM; var plResultParam : LRESULT); safecall; // Called by Windows Media Player to render a windowed visualization. procedure RenderWindowed(var pData : TimedLevel; fRequiredRender : BOOL); safecall; end; var TimedLvl : TimedLevel; implementation end. Ich wollte mich einfach mal schlau machen bei den Profis hier bevor ich das alles umschreibe. Beim Interface kein Problem aber es hängen ja noch ein paar mehr codezeilen da dran. Zitat:
Werde mich dann mal drangeben das neu zu implementiern. gruss |
AW: Procedure Safecall > function?
Ich verstehe zwar deinen Code nicht, aber vielleicht hilft dir folgende Information:
Safecall ist dasselbe wie stdcall nur mit HResult als Rückgabewert. Es passiert in etwa folgendes:
Delphi-Quellcode:
bzw, wenn man schon eine Funktion hat:
//folgende Routine:
procedure doX; safecall; begin ... end //ist identisch mit function doX:HResult; stdcall; begin try ... result:=s_ok; except result:=irgendeinfehler; end; end;
Delphi-Quellcode:
//aus
function getX:Integer;safecall; //wird function getX(out x:Integer):HResult;stdcall; //der Rückgabewert kommt an das Ende der Parameterliste Und es passiert nicht nur das, auch Delphi macht beim Aufrufen solcher Funktionen noch ein bisschen Hokuspokus. Es sortiert nicht nur die Parameter und Rückgabewerte um, sondern es ruft auch automatisch nach jeder safecall-Routine eine Funktion auf, die den Rückgabewert - also HResult - testet und ggf. wieder eine Exception wirft. Damit schafft man es in dem ganzen COM-Wirrwarr automatisch aus eine Exception einen Rückgabewert und daraus wieder eine Exception zu basteln ohne dein Zutun. Denn Exceptions (also Objekte) können nur schwer über DLL-Grenzen hinaus verschoben werden. Es ist ja zwangsläufig so, dass die Exceptions von der DLL(oder COM-Klasse) erzeugt werden und dann hast du sie im Hauptprogramm und kannst sie nicht freigeben. Deswegen dieser WorkAround. So, ich hoffe, du weißt jetzt warum es safecall gibt (falls das nicht eh schon der Fall war) und kannst daraus dein weiteres Vorgehen ableiten. Edit: Konnte man nicht beim automatischen TLB-Import einstellen, ob man safecall in stdcall umwandeln will? Edit2: In Delphi 7 habe ich keine Einstelloptionen gefunden aber auf der Kommandozeile funktioniert es:
Code:
-P+ sagt dass er eine Pascall-Datei erzeugen soll
tlibimp -P+ -Ps- <typelib>
und -Ps- sagt keine safecall-Routinen. |
AW: Procedure Safecall > function?
Zitat:
Zitat:
Zitat:
Danke für die Infos werden bestimmt auch anderen das Thema näher bringen. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:22 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