AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

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

Ein Thema von philipp.hofmann · begonnen am 16. Jan 2020 · letzter Beitrag vom 20. Jan 2020
Antwort Antwort
Seite 1 von 2  1 2   
philipp.hofmann

Registriert seit: 21. Mär 2012
Ort: Hannover
842 Beiträge
 
Delphi 10.4 Sydney
 
#1

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

  Alt 16. Jan 2020, 13:20
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
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 16. Jan 2020, 14:07
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.
  Mit Zitat antworten Zitat
philipp.hofmann

Registriert seit: 21. Mär 2012
Ort: Hannover
842 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 16. Jan 2020, 15:42
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
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 16. Jan 2020, 16:10
Hat devicename eine gültige Addresse im Debugger, wenn du die Maus drüber hältst, bevor UTF8ToString aufgerufen wird?
  Mit Zitat antworten Zitat
philipp.hofmann

Registriert seit: 21. Mär 2012
Ort: Hannover
842 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 16. Jan 2020, 19:34
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'}
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
208 Beiträge
 
#6

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 17. Jan 2020, 08:02
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
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 17. Jan 2020, 10:58
Zippe uns doch mal ein Minimal-Beispiel zusammen (Projekt, Quelltexte, benötigte DLLs), damit wir das selbst debuggen können.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.269 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 17. Jan 2020, 11:07
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.
Heiko
  Mit Zitat antworten Zitat
Friedhelm Drecktrah
(Gast)

n/a Beiträge
 
#9

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 17. Jan 2020, 16:26
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ß

Geändert von Friedhelm Drecktrah (17. Jan 2020 um 16:56 Uhr)
  Mit Zitat antworten Zitat
philipp.hofmann

Registriert seit: 21. Mär 2012
Ort: Hannover
842 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Rückgabe-Pointer PUTF8String aus DLL in String umwandeln?

  Alt 17. Jan 2020, 17:25
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 17:05 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