Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Enum verursacht eine ungültige gleitkommaoperation in Kernel32 (https://www.delphipraxis.net/189697-enum-verursacht-eine-ungueltige-gleitkommaoperation-kernel32.html)

EWeiss 11. Jul 2016 17:12

Enum verursacht eine ungültige gleitkommaoperation in Kernel32
 
Mein Enum

Delphi-Quellcode:
  TPlayState   = (psError = -1, psStop = 0, psPlay = 1,
                   psIsPlaying = 2, psPause= 3,
                   psPrevTitle = 4, psNextTitle = 5,
                   psSetPlaylistTitle = 6, psGetPlaylistTitlePos = 7,
                   psSetPlaylistPos = 8, psGetSelectedTitlePos = 9,
                   psPlaylistClear = 10, psAddPlaylistTitle = 11);
erweitere ich nun das Enum um einen Eintrag verursacht dieser Eintrag eine ungültige gleitkommaoperation unter VB6.

Die Callback sieht so aus.

Delphi-Quellcode:
TBASSVIS_STATECALLBACK = procedure(NewState: TPlayState); stdcall;
var
  AmpStateCallback : TBASSVIS_STATECALLBACK;
Der neue Entrag..
Delphi-Quellcode:
psExternalClose = 12


wird dann so übergeben
Delphi-Quellcode:
      if (assigned(AmpStateCallback)) then
        AmpStateCallback(psExternalClose );
funktioniert alles unter Delphi aber nicht mit VB6.

Das Problem ist das ich den DatenTyp (integer) mit den Enum nicht übergeben kann der typ der dann in VB6 ankommt "könnte" also variant sein.
Wenn also Variant verwendet wird löscht die Callback an ihrem Ende zu viel vom Stack.
Würde ich jetzt zumindest mal vermuten. ;)

Wie könnte ich die Callback umbauen so das ich von dem Enum wegkomme?

gruss

Medium 11. Jul 2016 22:48

AW: Enum verursacht eine ungültige gleitkommaoperation in Kernel32
 
Sobald man Interaktionen zwischen Sprachen hat, sollte man am besten Enums durch einfache Konstanten ersetzen. Enums sind kein Standard-Typ, und es hat sich imho auch nie eine wirkliche Standardimplementierung etabliert, so dass hier vermutlich jeder Compiler das Eigensüppchen brodelt. Ist zwar dann vom Interface her nicht mehr so nett anzuschauen und muss mit etwas mehr Kommentararbeit garniert werden wenn auch andere den Code leicht lesen können müssen, aber das ist die Lösung, die mir da fast ausschließlich über den Weg läuft.
Nimmt man dann auch noch brav typisierte Konstanten (VB6 kann glaube ich auch auf einen Typ festgenagelt werden wenn man es will, oder?), dann sollte es eigentlich keine Probleme mehr geben. Sieht dann halt so aus:

Delphi-Quellcode:
const
// PlayState Konstanten
  psError             : SmallInt = -1;
  psStop              : SmallInt = 0;
  psPlay              : SmallInt = 1;
  psIsPlaying         : SmallInt = 2;
  psPause             : SmallInt = 3;
  psPrevTitle         : SmallInt = 4;
  psNextTitle         : SmallInt = 5;
  psSetPlaylistTitle  : SmallInt = 6;
  psGetPlaylistTitlePos: SmallInt = 7;
  psSetPlaylistPos    : SmallInt = 8;
  psGetSelectedTitlePos: SmallInt = 9;
  psPlaylistClear     : SmallInt = 10;
  psAddPlaylistTitle  : SmallInt = 11;

type
  TBASSVIS_STATECALLBACK = procedure(NewState: SmallInt); stdcall; // Gültige Werte siehe "PlayState Konstanten" im Header

var
  AmpStateCallback : TBASSVIS_STATECALLBACK;

.
.
.

  if (assigned(AmpStateCallback)) then
    AmpStateCallback(psExternalClose);
SmallInt heisst in VB6 übrigens "Short". Schnell mit dem Delphi-ShortInt verwechselt, der aber nur 1 Byte groß ist. (Das hat mich schon immer sporadisch verwirrt.)

Eine schlauere Lösung die zugleich simpel umzusetzen und zu nutzen wäre fällt mir nicht spontan ein.

Edit: Grrrr! So schön eingerückt, und der "nette" DP Code-Parser zeigt immer noch nicht mehr als 1 Leerzeichen am Stück an. GRRRRRR! Warum!?

EWeiss 11. Jul 2016 22:59

AW: Enum verursacht eine ungültige gleitkommaoperation in Kernel32
 
Danke dir werde deine Lösung mal versuchen und damit prüfen ob es wirklich an den Enum "Datentypen" liegt.

gruss

EWeiss 11. Jul 2016 23:34

AW: Enum verursacht eine ungültige gleitkommaoperation in Kernel32
 
Habe es jetzt geändert..
Hat nichts mit dem Enum zu tun ich bekomme ein StackOverflowException in C#.
Habe im Moment keine Idee wie ich das beheben soll.

Vielleicht ist mein Ansatz auch falsch.

Ich gehe so vor.
Ich starte ein Plugin und setze es als Parent in ein Fenster.
Schließe ich das Fenster dann funktioniert alles normal.
Schließe ich das Plugin im Fenster dann bleibt das Fenster sichtbar.
Das Plugin schickt die Message WM_CLOSE.. und mein Thread wird beendet.

Jetzt sende ich über die Callback die Variable psExternalClose
Delphi-Quellcode:
   
if (assigned(AmpStateCallback)) then
  AmpStateCallback(psExternalClose);

Result := 0;
ExitThread(0);
In Delphi werte ich diese dann so aus.

Delphi-Quellcode:
    psExternalClose:
      begin
        if frm_Gen.Visible then
        begin
          mVisParam.VisHandle := 0;
          frmMain.InfoTimer1.Enabled := false;
          frm_Gen.Hide;
          frm_Gen.Close;
        end;
      end;
Das Fenster wird geschlossen und alles ist ok.

Funktioniert in VB6 nicht (ungültige gleitkommaoperation)
und in C# StackOverflowException

Code:
       
case BASSVIS_PLAYSTATE.ExternalClose:
  if (resWin != null)
    if (resWin.Visibility == Visibility.Visible)
    {
      mVisParam.VisHandle = 0;
      resWin.Close();
      resWin = null;
    }
    break;
Finde den Fehler einfach nicht.

gruss

EWeiss 12. Jul 2016 00:32

AW: Enum verursacht eine ungültige gleitkommaoperation in Kernel32
 
OK in C# habe ich es gefixt..
Das Problem lag daran weil ich die ResizeForm aus einem anderen Thread schließen muss.

Code:
        case BASSVIS_PLAYSTATE.ExternalClose:
          Dispatcher.Invoke(() =>
          {
            if (resWin != null)
              if (resWin.Visibility == Visibility.Visible)
              {
                // Viz is Close from External set VisHandle to 0
                mVisParam.VisHandle = 0;

                resWin.Close();
                resWin = null;
              }
          });
          break;
EDIT:
Mit VB6 geht so..
Code:
Case psExternalClose
    If GenVisible Then
        mVisParam.Vishandle = 0
        Form1.Timer1.Enabled = False
        PostMessage frmGen.hwnd, WM_CLOSE, 0, 0
    End If
Ich darf die Form nicht direkt ansprechen.
Was für ein Kram.

gruss


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