AGB  ·  Datenschutz  ·  Impressum  







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

Procedure Safecall > function?

Ein Thema von EWeiss · begonnen am 30. Jul 2012 · letzter Beitrag vom 31. Jul 2012
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

Procedure Safecall > function?

  Alt 30. Jul 2012, 17:14
Ich möchte eine procedure Safecall überschreiben so das ich das ergebnis zurückgeliefert bekomme.

Delphi-Quellcode:
IWMPEffects2 = interface(IWMPEffects)
  ['{695386EC-AA3C-4618-A5E1-DD9A8B987632}']
....
procedure Destroy; safecall;
...
Das Plugin behandelt es so..
Delphi-Quellcode:
procedure TVisualization.IWMPEffects2_Destroy;
begin
  FhwndParent := 0;
end;
Laut MS..

Zitat:
C++
HRESULT Destroy();
Parameters
This method has no parameters.

Return value
This method returns an HRESULT.

Remarks
This method is used only by windowed visualizations. Windowless visualizations should simply return S_OK.
Daher bin ich was durcheinander da einmal procedure und andererseits laut MS function ?

Wie das Interface casten damit es richtig verarbeitet wird?
Ich würde es ja so schreiben.

Delphi-Quellcode:
function Destroy(): Bool;
begin
  result := false;

  if Assigned(_IWmpEffects2) then
    if _IWmpEffects2.Destroy = S_OK then
      result := true
end;
Nur eine procedure erlaubt ja bekanntlich keinen Result Type.
Zur zeit sieht es so aus..
Delphi-Quellcode:
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;
Aber dann weiss ich nicht ob das Plugin sich zu dieser zeit
richtig beendet hat.

gruss

Geändert von EWeiss (31. Jul 2012 um 08:43 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: Procedure Savecall > function?

  Alt 31. Jul 2012, 08:34
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

Geändert von EWeiss (31. Jul 2012 um 08:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Procedure Safecall > function?

  Alt 31. Jul 2012, 09:05
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Procedure Safecall > function?

  Alt 31. Jul 2012, 09:21
Delphi-Quellcode:
{' 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.
Das ist das besagte Interface.
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:
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.
OK.. Danke dir
Werde mich dann mal drangeben das neu zu implementiern.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#5

AW: Procedure Safecall > function?

  Alt 31. Jul 2012, 10:56
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:
//folgende Routine:
procedure doX; safecall;
begin
...
end

//ist identisch mit
function doX:HResult; stdcall;
begin
  try
    ...
    result:=s_ok;
  except
    result:=irgendeinfehler;
  end;
end;
bzw, wenn man schon eine Funktion hat:
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:
tlibimp -P+ -Ps- <typelib>
-P+ sagt dass er eine Pascall-Datei erzeugen soll
und -Ps- sagt keine safecall-Routinen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.

Geändert von sirius (31. Jul 2012 um 11:17 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Procedure Safecall > function?

  Alt 31. Jul 2012, 16:31
Zitat:
Safecall ist dasselbe wie stdcall nur mit HResult als Rückgabewert.
Ahh war mir so nicht bekannt.

Zitat:
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.
Was ich wußte..
Zitat:
Zu Safecall:
Safecall erzeugt ja selber den OLE-Error wenn ein COM-Aufruf nicht funktioniert.
Aber nicht wie, wo, was, da ab geht damit ein Exeption geworfen wird.
Danke für die Infos werden bestimmt auch anderen das Thema näher bringen.

gruss
  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 04:44 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