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/)
-   -   C++ Struct übergabe problem (https://www.delphipraxis.net/182303-struct-uebergabe-problem.html)

EWeiss 16. Okt 2014 09:43


Struct übergabe problem
 
Was mach ich falsch das meine Daten aus C++ nicht so an meine DLL(Delphi) übergeben werden wie angewiesen?

C++ Anwendung..
Code:
void SetupBassVis()
{
   // TEMP: Temporarily load a plugin

   //////////////////////////////////////////////////////////////////////////
   // ----------------------------------------------------\/
   BASSVIS_KIND_T pluginKind = lastVisParam.Kind = BASSVISKIND_SONIQUE;

   BOOL success = BASSVIS_Init(pluginKind, hWnd);
   RECT wndRect;
   if (success)
   {
      GetWindowRect(hWnd, &wndRect);
      exec.Left = 0;
      exec.Top = 0;
      exec.Width = wndRect.right - wndRect.left;
      exec.Height = wndRect.bottom - wndRect.top;

      switch (pluginKind)
      {
      case BASSVISKIND_WINAMP:
         {
            BASSVIS_WINAMP_SetStateCallback( BASSVIS_StateCallback );

            exec.Pluginfile = "Plugins\vis_milk.dll";
            exec.AMP_Moduleindex = 0;
            exec.AMP_UseOwnW1 = 1;   // 
            exec.AMP_UseOwnW2 = 1;   //
            break;
         }
      case BASSVISKIND_SONIQUE:
         {
            exec.Pluginfile = "Ball.svp";
            exec.SON_ConfigFile = "vis.ini";
            exec.SON_UseOpenGl = true;
            exec.SON_ParentHandle = hWnd;
            exec.SON_ViewportHeight = 600;
            exec.SON_ViewportWidth = 800;
            exec.SON_ShowFPS = true;
            exec.SON_ShowPrgBar = true;
            exec.SON_UseCover = true;
            break;
         }
      case BASSVISKIND_WMP:
         {
            // Call FindPlugins once, otherwise ExecutePlugin doesn't work for WMP
            // Alchemy {0AA02E8D-F851-4CB0-9F64-BBA9BE7A983D}
            char *pluginList = BASSVIS_FindPlugins(pluginKind, "{0AA02E8D-F851-4CB0-9F64-BBA9BE7A983D}", 0, ",");
            exec.WMP_PluginIndex = 0;
            exec.WMP_PresetIndex = 0;
            exec.WMP_SrcVisHandle = hWnd;
            exec.WMP_CoInit = BASSVIS_CoInit::COINIT_NONE;
         }
      }

      BASSVIS_ExecutePlugin(&exec, &lastVisParam);

      switch (pluginKind)
      {
      case BASSVISKIND_WINAMP:
         {
            if (lastVisParam.VisHandle != 0)
            {
               // Get HWND from Winamp Dummy Window
               HVIS visWindowHandle = lastVisParam.VisHandle;

               // Send the last active Playlist index to visplugin
               BASSVIS_SetPlayState(&lastVisParam, psSetPlaylistPos, 0);

               // SendMessage Playing Status
               BASSVIS_SetPlayState(&lastVisParam, psPlay);

               // Check IsPlaying
               BASSVIS_SetPlayState(&lastVisParam, psIsPlaying);

               HWND hWndGen = lastVisParam.VisGenWinHandle;
               if (hWndGen != 0 && (exec.AMP_UseOwnW1 || exec.AMP_UseOwnW2))
                  BASSVIS_SetVisPort(&lastVisParam, hWndGen, hWnd, 0, 0, exec.Width, exec.Height);
            }
            break;
         }

      case BASSVISKIND_WMP:
         {
            if (lastVisParam.VisHandle != 0)
            {
               info.Channels = 2;
               info.SampleRate = 44100;
               info.SongTitle = "test";
               BASSVIS_SetInfo(&lastVisParam, &info);

               BASSVIS_SetPlayState(&lastVisParam, psPlay);
               BASSVIS_SetOption(&lastVisParam, BASS_VIS_CONFIG_FFTAMP, 128);   // TODO
            }

            break;
         }
      case BASSVISKIND_SONIQUE:
         BASSVIS_SetOption(&lastVisParam, BASS_SONIQUEVIS_CONFIG_RENDERTIMING, 25);
         BASSVIS_SetOption(&lastVisParam, BASS_SONIQUEVIS_CONFIG_USESLOWFADE, 1);
         BASSVIS_SetOption(&lastVisParam, BASS_SONIQUEVIS_CONFIG_SLOWFADE, 3);
         break;
      }

      if (hStream != 0)
         BASSVIS_RenderChannel(&lastVisParam, hStream, false);
   }
}
Code:
typedef struct {
    char* Pluginfile;           // path to Plugin kind
    DWORD AMP_UseOwnW1;         // flags for Winamp (ownHDC)
    DWORD AMP_UseOwnW2;         // flags for Winamp (ownHDCW2)
    DWORD AMP_Moduleindex;      // Modul-index for Winamp
    BOOL AMP_UseFakeWindow;    // Create a own Window for WindowMessages
    HWND SON_ParentHandle;     // Parent Windowhandle
    char* SON_ConfigFile;       // path to configfile Sonique
    BOOL SON_UseOpenGl;        // Use OpenGL instead of GDI
    int  SON_ViewportWidth;      // Stretch Width
    int  SON_ViewportHeight;     // Stretch Height  
    bool SON_ShowPrgBar;        // Show Progressbar
    bool SON_ShowFPS;           // ShowFPS
    bool SON_UseCover;          // Show Cover
    int  WMP_PluginIndex;      // Pluginindex für WMP;
    int  WMP_PresetIndex;      // Presetindex für WMP;
    HWND WMP_SrcVisHandle;     // ContainerVisHandle für WMP;
      BASSVIS_CoInit WMP_CoInit;
    HWND BB_ParentHandle;      // Parent Windowhandle
    BOOL BB_ShowFPS;           // Show FPS
    BOOL BB_ShowPrgBar;        // Show Progressbar
    HDC  AIMP_PaintHandle;     // Painthandle für Aimp2
    int  Width;                // SrcWindow width
    int  Height;               // SrcWindow height
    int  Left;                 // SrcWindow left
    int  Top;                  // SrcWindow top
} BASSVIS_EXEC;
Beispiel: Oben im Code das erste..
Code:
case BASSVISKIND_SONIQUE:
Wenn ich hier die Parameter festlege und an meine Delphi DLL übergebe werden diese falsch übergeben.
Es scheint so das die Struct in C++ mit der in Delphi nicht übereinstimmt (Ist aber die gleiche vom Aufbau her).

Delphi-Quellcode:
  PBASSVIS_EXEC = ^TBASSVIS_EXEC;
  TBASSVIS_EXEC = record
    Pluginfile           : PAnsiChar; // Dateiname des Plugins
                                       // für Sonique, Winamp, BassBox
    AMP_UseOwnW1          : DWORD;    // Flag für Winamp (ownHDC)
    AMP_UseOwnW2          : DWORD;    // Flag für Winamp (ownHDCW2)
    AMP_Moduleindex      : DWORD;    // Modul-index für Winamp
    AMP_UseFakeWindow    : BOOL;     // Create a own Window for WindowMessages
    SON_ParentHandle     : HWND;     // Parent Windowhandle
    SON_ConfigFile       : PAnsiChar; // Dateiname der Konfiguration für Sonique
    SON_UseOpenGL        : BOOL;     // Use OpenGL instead of GDI
    SON_ViewportWidth    : integer;  // Stretch Width
    SON_ViewportHeight   : integer;  // Stretch Height
    SON_ShowPrgBar       : BOOL;     // Progressbar anzeigen
    SON_ShowFPS          : BOOL;     // Frames pro Sekunde anzeigen
    SON_UseCover         : BOOL;     // Cover anzeigen
    WMP_PluginIndex      : integer;  // Pluginindex
    WMP_PresetIndex      : integer;  // Presetindex
    WMP_SrcVisHandle     : HWND;     // Parent Windowhandle
    WMP_CoInit           : TBASSVIS_CoInit;
    BB_ParentHandle      : HWND;     // Parent Windowhandle
    BB_ShowFPS           : BOOL;     // Frames pro Sekunde anzeigen
    BB_ShowPrgBar        : BOOL;     // Progressbar anzeigen
    AIMP_PaintHandle     : HDC;      // Painthandle für Aimp2
    Width                : integer;  // Fensterbreite
    Height               : integer;  // Fensterhöhe
    Left                 : integer;  // Left
    Top                  : integer;  // Top
  end;
Hab es schon mit Packed Record versucht macht aber keinen unterschied.

Code:
BASSVIS_ExecutePlugin(&exec, &lastVisParam);
lastVisParam soll dann die Handles der Plugins enthalten bzw. zurückgeben.

VB, Delphi, C#, VB.NET funktioniert soweit alles.
Es muss also ein Problem bei der Übersetzung des Header File für meine DLL vorliegen.
Hab sie mal angehängt.


gruss

Blup 16. Okt 2014 10:07

AW: Struct übergabe problem
 
Stimmt die Art der Parameterübergabe mit der in der DLL deklarierten Art überein.
Stimmt die Größe des Records (SizeOf) mit der Größe der Struktur in Byte-Anzahl überein.

Verweist char* wirklich auf einen Ansistring (PAnsiChar).

Entspricht "int" einem Delphi-32Bit-Integer.

Entspricht "BOOL" einen Delphi-32Bit-Boolean.
Im Delphi ist True = 1, im C++ True = -1, wenn in Delphi sauber programmiert wurde (kein Vergleich mit True) spielt das aber keine Rolle.

EWeiss 16. Okt 2014 10:18

AW: Struct übergabe problem
 
Zitat:

Entspricht "BOOL" einen Delphi-32Bit-Boolean.
Ich verwende wegen der Kompatibilität ausschließlich LongBool dürfte also eigentlich kein Problem machen.
In VB6 ist True auch -1 da gibt es keine Probleme.

Zitat:

Verweist char* wirklich auf einen Ansistring (PAnsiChar).
Denke ich schon denn es wird mir das richtige Plugin übergeben.
Die Struct(exec) wird in C++ auch richtig gefüllt kommt aber in der Delphi DLL mit falschen werten an.

Zitat:

Entspricht "int" einem Delphi-32Bit-Integer.
int: 4 Bytes 32Bit

sollte stimmen.

Delphi-Quellcode:
  PBASSVIS_PARAM = ^TBASSVIS_PARAM;
  TBASSVIS_PARAM = record
    VisHandle       : HVIS;           // VisHandle
    VisGenWinHandle : DWORD;          // General Vis Window Handle W5
    Kind            : TBASSVIS_KIND_T; // Aktive Plugin Art
  end;

procedure BASSVIS_ExecutePlugin(Param: PBASSVIS_EXEC;
    var Base: TBASSVIS_PARAM
); stdcall; external dllfile;

Code:
typedef struct {
    HVIS VisHandle;         // VisHandle
    HWND VisGenWinHandle;    // General Vis Window Handle W5
    BASSVIS_KIND_T Kind;     // Plugin kind   
} BASSVIS_PARAM;

void BASSVISDEF(BASSVIS_ExecutePlugin)(BASSVIS_EXEC* Param, BASSVIS_PARAM* Base);
Danke!

gruss

Blup 16. Okt 2014 10:53

AW: Struct übergabe problem
 
Versuch:
Code:
void __stdcall BASSVISDEF(BASSVIS_ExecutePlugin)(BASSVIS_EXEC* Param, BASSVIS_PARAM* Base);

EWeiss 16. Okt 2014 11:06

AW: Struct übergabe problem
 
Zitat:

Zitat von Blup (Beitrag 1276150)
Versuch:
Code:
void __stdcall BASSVISDEF(BASSVIS_ExecutePlugin)(BASSVIS_EXEC* Param, BASSVIS_PARAM* Base);

Danke ;)
Aber _stdcall ist schon definiert. "Siehe WINAPI f"
Gut konntest du ja nicht wissen. :)

Code:
#ifndef BASSVISDEF
#define BASSVISDEF(f) WINAPI f
#endif
Hab aber schon zwei Fehler gefunden.
Das verändert die Größe des Records
Code:
bool SON_ShowPrgBar; 1 Bytes
ist nicht gleich..
Code:
BOOL SON_ShowPrgBar; 4 Bytes
Code:
exec.SON_ShowFPS = true;
müsste dann
Code:
exec.SON_ShowFPS = TRUE;
sein.

gruss

EWeiss 16. Okt 2014 11:58

AW: Struct übergabe problem
 
@Blup

Danke für deine Hilfe funktioniert jetzt alles lag am BOOL
dadurch wurde die Größe des Rekords verändert.

gruss

TiGü 16. Okt 2014 12:44

AW: Struct übergabe problem
 
Darum macht man sich immer als ersten Parameter im record ein StructSize : Integer/DWORD und vergleicht diesen Wert bei Empfang und reagiert entsprechend drauf.
Vgl. diverse Windows-APIs wo structs/records ausgetauscht werden.

EWeiss 16. Okt 2014 12:52

AW: Struct übergabe problem
 
Zitat:

Zitat von TiGü (Beitrag 1276193)
Darum macht man sich immer als ersten Parameter im record ein StructSize : Integer/DWORD und vergleicht diesen Wert bei Empfang und reagiert entsprechend drauf.
Vgl. diverse Windows-APIs wo structs/records ausgetauscht werden.

Kleines Beispiel?
Keine Idee was du genau meinst.

gruss

TiGü 16. Okt 2014 13:22

AW: Struct übergabe problem
 
Zitat:

Zitat von EWeiss (Beitrag 1276198)
Zitat:

Zitat von TiGü (Beitrag 1276193)
Darum macht man sich immer als ersten Parameter im record ein StructSize : Integer/DWORD und vergleicht diesen Wert bei Empfang und reagiert entsprechend drauf.
Vgl. diverse Windows-APIs wo structs/records ausgetauscht werden.

Kleines Beispiel?
Keine Idee was du genau meinst.

Delphi-Quellcode:
program Project3;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Winapi.Windows;

type
  TMyRecord = record
    StructSize : DWORD;
    MyHandle : THandle;
    MyBoolValue : BOOL;
    MyIntValue : Int32;
  end;

  procedure Foo(const ARecord : TMyRecord);
  begin
    if ARecord.StructSize <> SizeOf(TMyRecord) then
      raise Exception.Create('Die Welt geht unter, weil StructSize: ' + IntToStr(ARecord.StructSize));

    Writeln('Alles gut, StructSize ist so groß wie sie sein soll: ' + IntToStr(SizeOf(TMyRecord)));
  end;

var
  MyFunnyRecord : TMyRecord;

begin
  try
    FillChar(MyFunnyRecord, SizeOf(MyFunnyRecord), 0);

    MyFunnyRecord.StructSize := SizeOf(MyFunnyRecord);
    Foo(MyFunnyRecord);

    MyFunnyRecord.StructSize := 666;
    Foo(MyFunnyRecord);
  except
    on E: Exception do
    begin
      Writeln(E.ClassName, ': ', E.Message);
      Readln;
    end;
  end;
end.

EWeiss 16. Okt 2014 13:30

AW: Struct übergabe problem
 
Leuchtet mir ein ;)
Danke für die Mühe..

gruss


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