Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Verwenden von IAMMediaContent (https://www.delphipraxis.net/198137-verwenden-von-iammediacontent.html)

Schokohase 5. Okt 2018 23:37

AW: Verwenden von IAMMediaContent
 
Zitat:

Zitat von EWeiss (Beitrag 1415070)
Nun Praxis und versuch sind zwei Dinge.
Die Anwendung stürzt nun ab bei FreeMem.

Müsste ich mir dann einmal konkret ansehen ...

EWeiss 5. Okt 2018 23:40

AW: Verwenden von IAMMediaContent
 
Zitat:

Zitat von Schokohase (Beitrag 1415071)
Zitat:

Zitat von EWeiss (Beitrag 1415070)
Nun Praxis und versuch sind zwei Dinge.
Die Anwendung stürzt nun ab bei FreeMem.

Was ich dir einen Beitrag vorher #9 auch erläutert habe.

Hallo ?

Ich mache es genauso wie von dir gezeigt und verwende genau deine Funktion.
Deine Antwort..
Zitat:

So sollte das tun
Aber tut es nicht.

Schritt für Schritt also siehe..
Delphi-Quellcode:
var
  FileName: string;
//..
      if InStr(lowercase(FileName), '//') = 1 then
      begin
        hr := KVideo_GetYoutubeFilterTitle(FileName);
        if SUCCEEDED( hr)then
          SKAERO_SetCTLText(gP.MainHandle, FileName);
      end else
      SKAERO_SetCTLText(gP.MainHandle, FileName);
Delphi-Quellcode:
function KVideo_GetYoutubeFilterTitle(out Title: string): HRESULT; stdcall;
begin
  result := E_FAIL;

  if not Assigned(EVMRPlayer) then
    exit;

  result := EVMRPlayer.GetYoutubeFilterTitle(Title);
end;
Delphi-Quellcode:
function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT;
var
  MediaContent: IAMMediaContent;
  pbstrTitle: PWideChar;
begin

  Result := E_FAIL;

  if not Assigned(srcFilter) then
    exit;

  if IsUrl then
  begin
    if DYDYoutubeFilter <> nil then
    begin
      srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent);
      Result := MediaContent.get_Title(pbstrTitle);
      if not SUCCEEDED(Result) then
        ReportError('YoutubeFilterTitle fails', Result)
      else
      begin
        Title := pbstrTitle;
        FreeMem(pbstrTitle); // Crash!
      end;
    end;
  end;
end;
Also was denn nun?
Deine Methode oder nicht!
Dein FreeMem lässt die Anwendung auf jeden fall abstürzen genau das gleiche wenn ich pbstrTitle auf Nil setze.
Mit der Freigabe wird das wohl nix oder?

gruss

Schokohase 6. Okt 2018 00:12

AW: Verwenden von IAMMediaContent
 
Ja, ich denke ich habe das Problem lokalisiert und kann dir morgen eine Lösung geben.

Ich vermute, dass die von dir verwendete Interface Deklaration von IAMMediaContent falsch ist. Aber dazu morgen mehr.

EWeiss 6. Okt 2018 00:18

AW: Verwenden von IAMMediaContent
 
Zitat:

Zitat von Schokohase (Beitrag 1415073)
Ja, ich denke ich habe das Problem lokalisiert und kann dir morgen eine Lösung geben.

Ich vermute, dass die von dir verwendete Interface Deklaration von IAMMediaContent falsch ist. Aber dazu morgen mehr.

Verstehe jetzt zwar nicht warum denn es wird mir der korrekte Titel zurückgegeben und das ist was ich erwarte.
Aber Ok.. Danke.

gruss

Schokohase 6. Okt 2018 07:13

AW: Verwenden von IAMMediaContent
 
So, jetzt nochmals nachgelesen und wenn man ganz exakt der Dokumentation folgt, dann müsste es so sein (nicht getestet)
Delphi-Quellcode:
uses
  ...
  Winapi.ActiveX;

function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT;
var
  MediaContent: IAMMediaContent;
  pbstrTitle: {Winapi.ActiveX.}TBSTR;
begin

  Result := E_FAIL;

  if not Assigned(srcFilter) then
    exit;

  if IsUrl then
  begin
    if DYDYoutubeFilter <> nil then
    begin
      srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent);
      Result := MediaContent.get_Title(pbstrTitle);
      if not SUCCEEDED(Result) then
        ReportError('YoutubeFilterTitle fails', Result)
      else
        begin
          Title := OleStrToString(pbstrTitle);
          {Winapi.ActiveX.}SysFreeString(pbstrTitle);
        end;
    end;
  end;
end;

KodeZwerg 6. Okt 2018 07:26

AW: Verwenden von IAMMediaContent
 
Hui das Ding kannte ich auch noch nicht, SysFreeString, müßte das nicht noch in dem " if DYDYoutubeFilter <> nil then" block aufgerufen werden anstelle nur im "if not SUCCEEDED(Result) then" block?

Schokohase 6. Okt 2018 07:40

AW: Verwenden von IAMMediaContent
 
Zitat:

Zitat von KodeZwerg (Beitrag 1415079)
Hui das Ding kannte ich auch noch nicht, SysFreeString, müßte das nicht noch in dem " if DYDYoutubeFilter <> nil then" block aufgerufen werden anstelle nur im "if not SUCCEEDED(Result) then" block?

Du musst es nur dann aufrufen, wenn du etwas zurückbekommen hast.

Ein Aufruf mit
Delphi-Quellcode:
nil
ist aber unkritisch von daher kann man es pauschal immer aufrufen, muss man aber nicht.

Denkbar ist also auch
Delphi-Quellcode:
uses
  ...
  Winapi.ActiveX;

function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT;
var
  MediaContent: IAMMediaContent;
  pbstrTitle: {Winapi.ActiveX.}TBSTR;
begin

  Result := E_FAIL;

  if not Assigned(srcFilter) then
    exit;

  if IsUrl then
  begin
    if DYDYoutubeFilter <> nil then
    begin
      srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent);
      pbstrTitle := nil;
      try
        Result := MediaContent.get_Title(pbstrTitle);
        if not SUCCEEDED(Result) then
          ReportError('YoutubeFilterTitle fails', Result)
        else
          Title := OleStrToString(pbstrTitle);
      finally
        {Winapi.ActiveX.}SysFreeString(pbstrTitle);
      end;
    end;
  end;
end;
PS

Wer meint, er kann darauf nicht reinfallen, weil er mit
Delphi-Quellcode:
ReportMemoryLeaksOnShutdown := true
arbeitet, dem sei gesagt, dass hier gar nichts gemeldet wird.

Kleiner Test (bei der Ausführung einen Blick auf den Taskmanager und den verwendeten Arbeitsspeicher haben)
Delphi-Quellcode:
uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class( TForm )
    Button1: TButton;
    FreeString_CheckBox: TCheckBox;
    procedure Button1_Click( Sender: TObject );
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses
  Winapi.ActiveX, System.StrUtils;

{$R *.dfm}

function GetString( AFreeString: boolean ): string;
var
  pbstrTemp: TBSTR;
begin
  pbstrTemp := StringToOleStr( DupeString( 'TestTest', 4096 ) );
  try
    Result := OleStrToString( pbstrTemp );
  finally
    if AFreeString
    then
      SysFreeString( pbstrTemp );
  end;
end;

procedure TForm1.Button1_Click( Sender: TObject );
var
  r: string;
  I: Integer;
begin
  ReportMemoryLeaksOnShutdown := True;
  for I := 1 to 4096 do
    begin
      r := GetString( FreeString_CheckBox.Checked );
    end;
end;

KodeZwerg 6. Okt 2018 08:20

AW: Verwenden von IAMMediaContent
 
Schön gezaubert und gut erklärt, Dankeschön dafür!:thumb:

edit
Miniexperiment:
Delphi-Quellcode:
  pbstrTemp := PWideChar( DupeString( 'TestTest', 4096 ) );
so scheint es sich selbst zu bereinigen.

EWeiss 6. Okt 2018 08:40

AW: Verwenden von IAMMediaContent
 
Wüsste jetzt nicht was TBSTR bringen soll.
PWideChar bleibt PWideChar egal wie am ende die Benennung ist.

Ist letztendlich auch nur ein PWideChar. ( POleStr = PWideChar; )

Die anderer Sache du schiebst hier einige dinge hin und her.
Was soll das mit out, var warum änderst du meine Ausgangsvariable von var nach out?

Schließlich verwendet die API var und nicht out.

Delphi-Quellcode:
function get_Title(var pbstrTitle: TBSTR): HResult; stdcall;
var nicht out!

gruss

mkinzler 6. Okt 2018 08:46

AW: Verwenden von IAMMediaContent
 
Emil, wenn Du keine Hilfe willst, warum fragst Du dann? :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:30 Uhr.
Seite 2 von 3     12 3      

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