Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   C/C++ struct in Delphi Record übersetzen (https://www.delphipraxis.net/154699-c-c-struct-delphi-record-uebersetzen.html)

nithdi 21. Sep 2010 17:21

C/C++ struct in Delphi Record übersetzen
 
Hallo allerseits.
Ich habe mich jetzt entscheiden, hier ein neues Thema zu eröffnen, weil ich mich bei meinem Problem total aufgegabelt habe.

Folgendes möchte ich tun:
Per Sendmessage einen Pointer zu einem Record an die Media Library von Winamp weitergeben. Dazu muss ich ein struct in ein record übersetzen, da die Winamp Media Library API in C/C++ geschreben ist. Winamp Media Library API

In der API Doku steht, dass ein Pointer zu einem struct als WPARAM übergeben werden soll - soweit kein Problem.
Das Struct sieht folgendermaßen aus:
Code:
typedef struct { 
  size_t size; // size of this struct  
  const wchar_t *playlistName; // set to NULL (or empty string) to prompt the user for a name
  const wchar_t *filename;
  int flags; // see PL_FLAG_* above  
  // the following two items can be optionally filled in (set to -1 otherwise)  
  // if they aren't set, the playlist file will have to be opened and parsed  
  // so prepopulating is faster (assuming if you already know the data)  
  int numItems; // set to -1 if you don't know.    
  int length; // in seconds, set to -1 if you don't know
} mlAddPlaylist;
Also habe ich dieses in einen Delphi Record "übersetzt":
Delphi-Quellcode:
type
  Playlist = record
    Size: Cardinal;
    Name: PWideChar;
    Path: PWideChar;
    Flags: Integer;
    Items: Integer;
    Length: Integer;
  end;
Allerdings scheint dort ein Fehler zu sein, denn wenn ich den record übergebe...:
Delphi-Quellcode:
const
  WM_ML_IPC = WM_USER + $1000;

var
  pl : Playlist;

...

pl.Name := 'Test';
pl.Path := 'C:\test.m3u';
pl.Flags := -1;
pl.Items := -1;
pl.Length := -1;
pl.Size := SizeOf(pl);
Sendmessage(hwndMediaLibrary, WM_ML_IPC, integer(@pl), $180); //$180 ist das Kommando an die ML, dass eine neue Playlist eingefügt werden soll
..macht Winamp daraus nur Müll.

Ich habe es schon mit vielen Variationen von Casts probiert, hatte aber bisher keinen Erfolg. Manchmal erscheinen in Winamp dann japanische Zeichen (spricht doch eigentlich für ein Problem ANSI <-> Unicode, oder?), oder auch mal eine neue leere Zeile.

Habe ich das Struct falsch übersetzt?

Vielen Dank für eure Hilfe!

shmia 21. Sep 2010 17:45

AW: C/C++ struct in Delphi Record übersetzen
 
Delphi-Quellcode:
// Delphi wandelt das String-Literal 'test' in einen WideString um,
// und schreibt die Adresse nach pl.Name
// Nach dem Befehl wird der temporäre Widestring entsorgt
pl.Name := 'Test';
Versuch mal das:
Delphi-Quellcode:
var
  pl : Playlist;
  wsName, wsPath : WideString;

...
wsName := 'Test';
wsPath := 'C:\test.m3u';
pl.Name := wsName;
pl.Path := wsPath;

nithdi 21. Sep 2010 18:27

AW: C/C++ struct in Delphi Record übersetzen
 
Hallo und danke für die schnelle Antwort.

Funktioniert leider nicht. Name und Path müssen ein LPCWSTR = Long Pointer to const Wide String(nach API Doku) sein. Das müsste doch in Delphi der PWideChar sein, oder irre ich mich da?

Habe zu deinem Beispiel deshab noch den cast auf PWideChar hinzugefügt:
Delphi-Quellcode:
pl.Name := PWideChar(wsName);
pl.Path := PWideChar(wsPfad);
Leider immernoch japanische Zeichen in Winamp. Ist vielleicht Winamp selbst der Übeltäter?

Bummi 22. Sep 2010 11:23

AW: C/C++ struct in Delphi Record übersetzen
 
Ergänzug zu shima:

hast Du wsName, wsPath : WideString;
auf dem Stack?, versuchs Du mal mit 'globalen' variablen.

nithdi 24. Sep 2010 10:14

AW: C/C++ struct in Delphi Record übersetzen
 
So.

Um den Thread zum Ende zu bringen, ich habs endlich geschafft.

Der Lösungsansatz mit den globalen Variablen hatte leider auch nicht funktioniert... also hab ich noch ein wenig rumprobiert.

Die Lösung war, die Pointer zu den Strings Name und Path, sowie den gesamten record schon vorher in den Speicherbereich von winamp zu kopieren (per WriteProcessMemory).
Dann einfach den Pointer zum Record an Winamp weitergeben und tada.. :)

Danke für eure Lösungsansätze.

Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:50 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