Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   C++ Events von Delphi to C++ (https://www.delphipraxis.net/193483-events-von-delphi-c.html)

EWeiss 4. Aug 2017 23:48

Events von Delphi to C++
 
Sorry ja ich nerve zur zeit. ;)

Die Events in Delphi.
Delphi-Quellcode:
  TPlayerEvent = (PlayEnded, ErrorEnded);
  CBEventNotice = procedure(Event: TPlayerEvent); stdcall;

  KVideo_Initialize: function(MediaWindow: HWND; EventNoticeFunc: CBEventNotice): BOOL; stdcall;
funktioniert von Delphi zu Delphi ohne nennenswerte Probleme.

Jetzt in C++ definiert.
Code:
enum TPlayerEvent {
  PlayEnded,
  ErrorEnded
};
typedef void ( * CBEventNotice )( TPlayerEvent );

BOOL KVIDEOPLAYERDEF(KVideo_Initialize)(HWND MediaWindow, CBEventNotice events);
Die Funktion welche die Events empfangen soll.
Code:
void OnPlayerEvent(TPlayerEvent event)
{
    if (event == PlayEnded)
    {
        KillTimer(MovieHandle, MOVIE_TIMER);
    }
}
Mein Problem es kommen nie welche an.
Was ist da falsch?

Habe es schon auf diese weise versucht geht aber auch nicht.
Code:
void _stdcall OnPlayerEvent(TPlayerEvent event)
{
    if (event == PlayEnded)
    {
        KillTimer(MovieHandle, MOVIE_TIMER);
    }
}
gruss

Zacherl 5. Aug 2017 02:42

AW: Events von Delphi to C++
 
Also wenn du es in Delphi mit
Delphi-Quellcode:
stdcall
deklariert hast, musst du das in C++ auf jeden Fall schonmal auch verwenden. Auch beim Typedef!

Jetzt ist die Frage:
Wird das Event wirklich nicht ausgelöst, oder stimmt nur der "Event Code" nicht? Lass mal eine MessageBox vor der Auswertung von
Delphi-Quellcode:
event
anzeigen.

Enums in C++ sind standardmäßig 4-Bytes groß, während sie bei Delphi dynamisch skalieren.

Du kannst jetzt entweder in Delphi das Enum per Compiler-Switch auf 4-Bytes vergrößern (oder als letztes Element ein
Delphi-Quellcode:
FORCE_DWORD = MAXINT
hinzufügen), oder du verkleinerst die Enum-Größe entsprechend im C++ Code. Hier würde ich dir generell zu typisierten Enums raten (Delphi Enums sind auch typesafe):
Code:
enum class PlayerEvent : std::uint8_t // #include <cstdint>
{
    PlayEnded,
    ErrorEnded
};
Statt
Delphi-Quellcode:
uint8_t
sind je nach Anzahl der Elemente dann auch andere Typen wie z.b.
Delphi-Quellcode:
uint16_t
, etc. Möglich.

Deine Abfrage sieht mit typisierten Enums dann so aus:
Code:
void _stdcall OnPlayerEvent(TPlayerEvent event)
{
    if (event == PlayerEvent::PlayEnded)
    {
        KillTimer(MovieHandle, MOVIE_TIMER);
    }
}

EWeiss 5. Aug 2017 02:50

AW: Events von Delphi to C++
 
Das Problem ist das wenn ich einen break Point setze in

Code:
 if (event = PlayEnded)
Ich niemals da rein komme wenn der Film endet.
In Delphi immer.

Daher bin ich mir nicht sicher ob meine Funktion bzw. das Event richtig ist.
Also das hier

Code:
typedef void ( * CBEventNotice )( TPlayerEvent );
gruss

EWeiss 5. Aug 2017 03:04

AW: Events von Delphi to C++
 
Bekomme dann 2 Fehler
Code:
Fehler (aktiv)   E0167   Das Argument vom Typ ""void (__stdcall *)(TPlayerEvent event)"" ist mit dem Parameter vom Typ ""TPlayerEvent"" inkompatibel.

Fehler   C2664   "BOOL KVideo_Initialize(HWND,TPlayerEvent)" : Konvertierung von Argument 2 von "void (__cdecl *)(TPlayerEvent)" in "TPlayerEvent" nicht möglich
cpp..
Code:
void _stdcall OnPlayerEvent(TPlayerEvent event)
{
    if (event == TPlayerEvent::PlayEnded)
    {
        KillTimer(MovieHandle, MOVIE_TIMER);
    }
}

if (KVideo_Initialize(MovieHandle, OnPlayerEvent))
h..
Code:
enum class TPlayerEvent : std::uint8_t {
  PlayEnded,
  ErrorEnded
};

typedef void ( * CBEventNotice )(TPlayerEvent);

BOOL KVIDEOPLAYERDEF(KVideo_Initialize)(HWND MediaWindow, TPlayerEvent callback);
EDIT:
Ok habe das geändert.
Jetzt lässt es sich wieder kompilieren.
Code:
BOOL KVIDEOPLAYERDEF(KVideo_Initialize)(HWND MediaWindow, CBEventNotice event);
Aber es wird immer noch kein Event ausgelöst. Hmmm...
Das kann ich nicht ändern.
Code:
typedef void _stdcall( * CBEventNotice )(TPlayerEvent);
produziert den Fehler.

Zitat:

Fehler (aktiv) E0651 Auf eine Aufrufkonvention darf kein geschachtelter Deklarator folgen.
Fehler C2059 Syntaxfehler: "("
Fehler C2061 Syntaxfehler: Bezeichner "CBEventNotice"
Fehler C2660 "KVideo_Initialize": Funktion akzeptiert keine 2 Argumente
gruss

Zacherl 5. Aug 2017 03:43

AW: Events von Delphi to C++
 
Zitat:

Zitat von EWeiss (Beitrag 1378128)
Code:
typedef void _stdcall( * CBEventNotice )(TPlayerEvent);
produziert den Fehler.

Zitat:

Fehler (aktiv) E0651 Auf eine Aufrufkonvention darf kein geschachtelter Deklarator folgen.
Fehler C2059 Syntaxfehler: "("
Fehler C2061 Syntaxfehler: Bezeichner "CBEventNotice"
Fehler C2660 "KVideo_Initialize": Funktion akzeptiert keine 2 Argumente

Da ist deine Syntax falsch (die ist aber zugegebenermaßen auch echt sehr eigen an dieser Stelle :stupid:). So muss es heißen:
Code:
typedef void (__stdcall *CBEventNotice )(TPlayerEvent);
Delphi-Quellcode:
_stdcall
mit einem "_" wird übrigens nur bei MSVC funktionieren, deshalb am besten immer 2 Unterstriche verwenden.

Edit:
Und ich glaube bei
Delphi-Quellcode:
if (KVideo_Initialize(MovieHandle, OnPlayerEvent))
fehlt noch der Adress-Operator, also
Delphi-Quellcode:
if (KVideo_Initialize(MovieHandle, &OnPlayerEvent))
(wobei das glaube ich bei den meisten Compilern sogar optional ist).

EWeiss 5. Aug 2017 03:56

AW: Events von Delphi to C++
 
Zitat:

die ist aber zugegebenermaßen auch echt sehr eigen an dieser Stelle
Er wurde von einem Übersetzung Tool so bereitgestellt (Nun gut ich halte nicht besonders viel davon)
Habe noch keins gesehen das wirklich gut funktioniert.
Das beste Tool ist immer noch der Kopf selbst (oder andere Köpfe) LOL.

Zitat:

fehlt noch der Adress-Operator
Ja nach deinen Änderungen. ;)
Vorher habe ich den nicht setzen können.

Habe jetzt alles so gemacht wie du mir es gesagt hast.
Danke für deine Zeit und Hilfe.

aber leider wird immer noch kein Event ausgelöst.
Da ich davon ausgehe das deine Änderungen richtig sind kann es nur noch an meiner DLL liegen.

Muss diese nochmal prüfen.
Was anderes fällt mir sonst nicht ein ;)

gruss

EWeiss 5. Aug 2017 04:42

AW: Events von Delphi to C++
 
OK es funktioniert nun.

Ich habe es mal mit der Delphi64Bit Anwendung getestet da war das gleiche Problem.
Das Event wurde nicht ausgelöst.

Habe mir dann nochmal die Dateitypen angesehen die verwendet werden musste dann feststellen das die Events in DirectShow wParam, LParam mit LongInt definiert waren.
Das war natürlich falsch deshalb ging es nicht.
Nach der Änderung auf LONG_PTR (INT64) funktioniert das ganze jetzt.

Da die Zeitmessung und die Positionen im Film ebenfalls mit INT64 definiert sind muss das natürlich gleich sein.
Andernfalls werden die Events nicht ausgelöst.

Danke für die richtigen Funktionen ohne die würde es immer noch nicht gehen.

gruss


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