Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Rückgabe-Pointer PUTF8String aus DLL in String umwandeln? (https://www.delphipraxis.net/203135-rueckgabe-pointer-putf8string-aus-dll-string-umwandeln.html)

philipp.hofmann 16. Jan 2020 12:20

Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Hi,

ich kämpfe gerade an den Details meiner FFMPEG-Anbindung, weil diese vom Hersteller der Bibliothek noch nicht vollständig implementiert ist.
Es geht gerade darum, den Namen des Ausgabe-Device zu ermitteln.

Hierfür ist zwar schon eine Methode in der sdl.dll vorgesehen, diese liefert aber nur einen Pointer auf einen UTF8String zurück:

Delphi-Quellcode:
function SDL_GetAudioDeviceName(index:Integer;iscapture:Integer):PUTF8String;
  cdecl;external libsdl;
SDL_GetAudioDeviceName:function(index:Integer;iscapture:Integer):PUTF8String;
  cdecl;
Habe ich hier von außen überhaupt die Chance den String hinter dem Pointer zu erhalten?
Hier sieht man, dass ich an sich richtig eine PUTF8String in einen String zurückwandeln kann ('Help me'),
aber mit dem Pointer aus dem DLL-Aufruf kann ich dies nicht tun, da gibt es dann eine EAccessViolation.

Delphi-Quellcode:
function TAVPlayer.getAudioDeviceName(index:integer):String;
var deviceName:PUTF8String;
    str1:String;
    str2:UTF8String;
begin
  str1:='Help me';
  str2:=UTF8Encode(str1);
  deviceName:=@Pointer(str2);
  result:=UTF8ToString(deviceName^);

  deviceName:=SDL_GetAudioDeviceName(index,0);
  //EAccessViolation:
  result:=UTF8ToString(deviceName^);
end;
Grüße, Philipp

TiGü 16. Jan 2020 13:07

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Delphi-Quellcode:
  deviceName:=SDL_GetAudioDeviceName(index,0);
 
 
  if Assigned(devicename) then
    result:=UTF8ToString(deviceName^)
  else
    result := '';
Grund:
https://wiki.libsdl.org/SDL_GetAudioDeviceName

Zitat:

Return Value
Returns the name of the audio device at the requested index, or NULL on error.

philipp.hofmann 16. Jan 2020 14:42

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Leider reicht dies nicht aus:

exception class : EAccessViolation
exception message : Zugriffsverletzung bei Adresse 000000000041BD58 in Modul 'icTrainer.exe'. Lesen von Adresse FFFFFFFFFFFFFFFF.

main thread ($2254):
0041bd58 +038 icTrainer.exe System UTF8ToUnicodeString
016c332f +05f icTrainer.exe AVPlayer 3087 +8 TAVPlayer.getAudioDeviceName

TiGü 16. Jan 2020 15:10

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Hat
Delphi-Quellcode:
devicename
eine gültige Addresse im Debugger, wenn du die Maus drüber hältst, bevor UTF8ToString aufgerufen wird?

philipp.hofmann 16. Jan 2020 18:34

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Eigentlich steht da im Debugger noch was vernünftiges drinnen, trotzdem kracht es:

Delphi-Quellcode:
function TAVPlayer.getAudioDeviceName(index:integer):String;
var deviceName,testName:PUTF8String;
    str1,testResult:String;
    str2:UTF8String;
begin
  str1:='Help me';
  str2:=UTF8Encode(str1);
  testName:=@Pointer(str2);
  testResult:=UTF8ToString(testName^);

  deviceName:=SDL_GetAudioDeviceName(index,0);
  result:=UTF8ToString(deviceName^);
end;
deviceName: $1B9D4E00 {''}
testName: $14F770 {'Help me'}

Incocnito 17. Jan 2020 07:02

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
In den Remarks steht, dass das ein "Mananged String" ist, du dich also nicht um die Freigabe kümmern sollst/darfst.
Könnte es sein, dass Delphi von sich aus was aufräumt und du deswegen Probleme bekommst?
Vielleicht klappt es, wenn du die Funktion nicht mit "PUTF8String" definierst, sondern schlicht als Pointer
und dann erstmal im Debugger (Stack, CPU-Adresse, whatever) schaust, ob du bei der zurückgegebenen Adresse was findest.
Dann könntest du vielleicht die Daten lokal kopieren (move), damit Delphi nicht das Original freigeben kann.
Ist jetzt nur ein Gedankengang, weiß auch nicht ob das wirklich stimmt, aber vielleicht hilft es den richtigen Weg zu finden.
Wenn's gar nicht anders geht vielleicht ein Mini-Programm schreiben und das hier bereit stellen.

LG Incocnito

TiGü 17. Jan 2020 09:58

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Zippe uns doch mal ein Minimal-Beispiel zusammen (Projekt, Quelltexte, benötigte DLLs), damit wir das selbst debuggen können.

hoika 17. Jan 2020 10:07

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Hallo,
in der Doku steht als Rückgabewert PChar (* char).
siehe auch hier

https://github.com/Laex/Delphi-OpenC.../sdl2/SDL2.pas

Einfach mal damit probieren.

Außerdem fehlt mit die Initialisierung der gesamten Sache.

(https://wiki.libsdl.org/SDL_GetAudioDeviceName)
This function is only valid after successfully initializing the audio subsystem.

Friedhelm Drecktrah 17. Jan 2020 15:26

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Das läuft bei mir:

program SDLDemo;

{$APPTYPE CONSOLE}
{$R *.res}

uses
System.SysUtils;

type
TSdlAudio = class
public
procedure GetAudioDeviceNames();
end;

const
SDL_INIT_TIMER = $00000001;
SDL_INIT_AUDIO = $00000010;
SDL_INIT_VIDEO = $00000020; // SDL_INIT_VIDEO implies SDL_INIT_EVENTS
SDL_INIT_JOYSTICK = $00000200; // SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS
SDL_INIT_HAPTIC = $00001000;
SDL_INIT_GAMECONTROLLER = $00002000; // SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK
SDL_INIT_EVENTS = $00004000;
SDL_INIT_SENSOR = $00008000;
SDL_INIT_NOPARACHUTE = $00100000; // compatibility; this flag is ignored.

DEVICE_TYPE_OUTPUT = 0;
DEVICE_TYPE_INPUT_CAPTURE = 1;

function SDL_Init(flags: integer): integer; cdecl; external 'SDL2.dll';
function SDL_GetNumAudioDevices(isCapture: integer): integer; cdecl; external 'SDL2.dll';
function SDL_GetAudioDeviceName(index: integer; isCapture: integer): PAnsiChar; cdecl; external 'SDL2.dll';

{ TSdlAudio }

procedure TSdlAudio.GetAudioDeviceNames();
var
initResult: integer;

numDevices: integer;
deviceId: integer;

deviceName: PAnsiChar;
begin
initResult := SDL_Init(SDL_INIT_AUDIO);
Writeln('initResult: ' + initResult.ToString());

numDevices := SDL_GetNumAudioDevices(0);
Writeln('numDevices: ' + numDevices.ToString());

for deviceId := 0 to numDevices - 1 do
begin
deviceName := SDL_GetAudioDeviceName(deviceId, DEVICE_TYPE_OUTPUT);
Writeln('deviceName: ' + deviceName);
end;
end;

var
sdlAudio: TSdlAudio;

begin
try
sdlAudio := TSdlAudio.Create;
sdlAudio.GetAudioDeviceNames();
sdlAudio.Free;

Writeln;
Writeln('Enter drücken...');
ReadLn;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;

end.


Gruß

philipp.hofmann 17. Jan 2020 16:25

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?
 
Diese SDL2.pas ist schon mal besser als die Version von http://www.flashavconverter.com/cont...yer-firemonkey.

Delphi-Quellcode:
var pDeviceName:PChar;
    deviceName:String;
    deviceNameList:TStringList;
    count,i:integer;
begin
    count:=SDL_GetNumAudioDevices(0);
    deviceNameList:=TStringList.Create();
    for i:=0 to count-1 do
    begin
      pDeviceName:=SDL_GetAudioDeviceName(0,0);
      deviceName:=UTF8ToString(pDeviceName^);
      deviceNameList.Add(deviceName);
    end;
end;
a) Hier kommt jetzt schon mal die richtige Anzahl an Devices zurück (was mir auch schon mal hilft),
b) nur für jedes Device kommt als Name ? zurück bei Verwendung von UTF8ToString(pDeviceName^)
Bei deviceName:=String(pDeviceName) oder deviceName:=StrPas(pDeviceName) oder deviceName:=Copy(pDeviceName, 1, maxInt) oder deviceName:=pDeviceName kommt 䕄䱌匠㈲〴⁔䤨瑮汥刨
楄灳慬⵹畁楤⥯ zurück


Damit bin ich an sich aber schon mal weiter. Nur läuft die Klasse nicht unter MacOS-64 (auch nicht, wenn ich den Type von TClose auf Integer setze).
Ich hoffe, dass Flash-AV-Converter hier die Tage die Funktion zur Verfügung stellt.

So einfach kann ich kein Beispiel-Projekt generieren, weil ich dies ja mit http://www.flashavconverter.com/cont...yer-firemonkey baue.
Müsste dann zuerst schauen, ob dies mit der Demo der Library auch gut zusammen geht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:43 Uhr.
Seite 1 von 2  1 2      

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