Autor Beitrag
Peter18
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Di 16.06.15 11:52 
Ein freundliches Hallo an alle,

immer Ärger mit den Pointern. :cry: Ich dachte die Tapi ist abgehakt, aber ein typischer Fall von denkste!

In diesem Fall soll ein Anrufmonitor den Anrufer zeigen. Aber mein Compiler scheint die Schnittstelle der Callback-Routine nicht korrekt zu erstellen. Ein bis zwei Anrufe werden signalisiert, dann ist Feierabend. Da auch ein Anrufmonitor aus den Internet nichts mehr sagt, gehe ich davon aus, das die TAPI zersägt worden ist. Nach Neustart geht es dann manchmal wieder, doch irgend wann ist auch das vorbei und es hilft nur die TAPI neu zu installieren.

Das steht in der Tapi.pas:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
    TTAPICallback = procedure(hDevice, dwMessage: DWORD; dwInstance, dwParam1,
    dwParam2, dwParam3: DWORD_PTR) stdcall;
//  +++++++++++++++ !! +++++++++++++++++++++++++++++++++++++++++++++
  {TLineCallback = procedure(hDevice, dwMessage: DWORD; dwInstance, dwParam1,
    dwParam2, dwParam3: DWORD_PTR) stdcall;}

  TLineCallback = TTAPICallback;
  LINECALLBACK = TLineCallback;
  {$EXTERNALSYM LINECALLBACK}


Das steht in meiner Unit:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
....
Type
  Ba  = Array [0..500of Byte;
  PBa = ^Ba;

procedure LineCallBack( hDev, Msg, Cbi, P1, P2, P3 : DWord );    stdcall;
....

Das Array dient zum kopieren der Rufnummern. Wenn ich die Type-Deklaration von dort unter "implementation" verschiebe, ändert sich die Fehlermeldung. Setze ich sie erneut an diese Stelle ändert sie sich jedoch nicht!

In dieser Zeile wird die "LineCallBack" angemeckert und das mit den unterschiedlichsten Fehlermeldungen.
ausblenden Delphi-Quelltext
1:
R  := lineInitialize( @Luh, HInstance, LineCallBack, PChar( 'Test' ), DC );					

Mal behauptet er die "LineCallBack" wäre nicht global deklariert, mal erwartet er ein "(" und findet ",". Mal geht es nur mit "@LineCallBack," und mal mit "LineCallBack,". Das Merkwürdige ist, mache ich die Änderung rückgängig (Auskommentieren) erscheint nicht immer der selbe Fehler wie zuvor.

Bei "procedure T_Tapi.WriteCallMon( B : Boolean );" wird nicht gemeckert, aber bei "procedure Dial( Nr: String; V : DWord; GeraetInd : DWord; Modem : Boolean );".

Bei dem Ganzen habe ich etwas die Peilung verloren, vielleicht kann mich jemand wieder auf Kurs bringen. Ist es vielleicht sinnvoll die CallBack in eine extra Unit zu stecken? Oder die CallBack einer Pointervariablen zuweisen? Oder kann ich die Deklaration in der Tapi.pas nutzen?

Ich hoffe auf einen guten Tipp und grüße von der sonnigen Nordsee

Peter
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Mi 17.06.15 13:22 
Deine LineCallback Funktion sollte so aussehen (analog zur TTAPICallback)

ausblenden Delphi-Quelltext
1:
procedure myLineCallback(hDevice, dwMessage: DWORD; dwInstance, dwParam1, dwParam2, dwParam3: DWORD_PTR) stdcall;					


und beim Aufruf solltest du @LineCallback uebergeben. Das geht auch nur wenn die Funktion keine Methode ist.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
unit bla;

interface

uses windows, usw;

procedure myLineCallback(hDevice, dwMessage: DWORD; dwInstance, dwParam1, dwParam2, dwParam3: DWORD_PTR) stdcall;

implementation

procedure myLineCallback(hDevice, dwMessage: DWORD; dwInstance, dwParam1, dwParam2, dwParam3: DWORD_PTR) stdcall;
begin
  // was machen
end;

// (die Funktion muss in keine Extra Unit ausgelagert werden, hier ist das nur als Beispiel, wenn du extern darauf zugreifen willst)


Ausserdem solltest dir auch mal lineInitializeEx anschauen


Achtung: eventl ist auch deine TTAPICallback falsch (DWORD_PTR wird in PDWORD sein) das ist dann nicht korrekt

ggf. hilft dir das:
gedemin.googlecode.c...trunk/Comp5/tapi.pas


Edit:
deine TTAPICallback ist falsch deklariert, msdn.microsoft.com/e...12%28v=vs.85%29.aspx
also stimmt mein Code oben nicht, du musst aber trotzdem @myLineCallback verwenden (und die Funktion sollte anders heissen als LINECALLBACK wenn du das schon deklariert hast)

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit

Für diesen Beitrag haben gedankt: Peter18
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Mi 17.06.15 17:16 
Hallo Daniel,

endlich kann ich mich auch mit dieser Antwort befassen. Dank Dir auch dafür!

Da bei MS
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
VOID FAR PASCAL lineCallbackFunc(
   DWORD hDevice,
   DWORD dwMsg,
   DWORD dwCallbackInstance,
   DWORD dwParam1,
   DWORD dwParam2,
   DWORD dwParam3
);
steht habe ich alles als "DWORD" deklariert. Die Ergebnisse waren ok. Aber vielleicht macht "PASCAL" den Untreschied. In meinem C++ Buch steht davon nichts, aber vielleicht hätte ich das Internet bemühen sollen.

Auf jeden Fall konnte ich das Ganze Übersetzen. Werd mal Testen und Berichten.

Grüße von der Nordsee wo es nach Regen aussieht

Peter
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Do 18.06.15 11:19 
Hallo Daniel,

die "CallBack" heißt bei mir jetzt "Line_CallBack" und hat Parameter wie in der "Tapi.pas". Es wird mir auch ein Anruf gemeldet. Manchmal ein Zweiter. Dann ist Sendepause. Erst wenn ich das Programm neu starte wird die CallBack wieder aufgerufen. Zur Kontrolle hatte ich mir einen tapibasierten Anrufmonitor aus dem Internet geholt. Der verhält sich genau so, wenn mein Programm läuft. Läuft er allein, wird aber jeder Anruf gemeldet. Offenbar zersägt irgendetwas die TAPI. Kann es sein, dass der Kompiler ein Problem mit der CallBack hat??

Grüße von der wolkigen Nordsee

Peter
SMO
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 120
Erhaltene Danke: 18


D2005 Personal
BeitragVerfasst: Do 18.06.15 15:36 
"PASCAL" ist die Aufrufkonvention, entspricht "stdcall".
Nein, der Kompiler hat kein Problem mit Callbacks. Wenn es nicht richtig funktioniert, muss noch irgendwo ein Fehler sein.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 18.06.15 16:40 
user profile iconSMO hat folgendes geschrieben Zum zitierten Posting springen:
"PASCAL" ist die Aufrufkonvention, entspricht "stdcall".
Nein, bei Pascal werden die Parameter von links nach rechts auf dem Stack abgelegt, bei stdcall von rechts nach links!
Es ist also hier wichtig das passende zu benutzen, sonst kommen die Parameter verkehrt herum an, sprich die falschen Werte werden an die Parameter übergeben.

Für diesen Beitrag haben gedankt: SMO
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Do 18.06.15 16:55 
Hallo SMO,

Dank Dir für die Antwort. Irgend wo anders ein Fehler? Preisfrage: Aber wo??

Vielleicht stimmt der Ablauf ja nicht und es fehlt irgend ein Schritt. Ich hoffe jemand kann mir dazu einen Tipp geben. In "Windows Telephony Programming" habe ich nichts dazu gefunden.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
Der Ablauf ist folgender:
  lineInitialize,
  lineOpen für alle "voice-Geräte"
In der "Line_CallBack":
  eingehender Anruf:  lineGetCallInfo ==> Rufnummern
  LINECALLSTATE_IDLE: lineDeallocateCall

Muß ich vielleicht ein CloseLine und dann wieder lineOpen machen???

Grüße von der Nordsee

Peter


Zuletzt bearbeitet von Peter18 am Do 18.06.15 17:07, insgesamt 1-mal bearbeitet
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Do 18.06.15 17:03 
Hallo Sebastian,

Dank Dir für die Klärung. Paßt das Ganze denn dann überhaupt zusammen? Die Reihenfolge scheint ja zu stimmen, denn bei "R := lineDeallocateCall( hDevice );" ist R = 0, also kein Fehler.

grüße von der Nordsee

Peter
SMO
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 120
Erhaltene Danke: 18


D2005 Personal
BeitragVerfasst: Do 18.06.15 17:13 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Nein, bei Pascal werden die Parameter von links nach rechts auf dem Stack abgelegt, bei stdcall von rechts nach links!

Stimmt, hatte ich ganz vergessen! Allerdings behandelt Win32 "PASCAL" als Synonym für "WINAPI", was beides "__stdcall" in C entspricht (siehe, und hier).

Die Frage ist also, stimmt die TTAPICallback Deklaration mit "stdcall" oder müsste es tatsächlich "pascal" sein? Ich habe TAPI noch nie benutzt, aber ich vermute stdcall wird schon korrekt sein.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 18.06.15 17:31 
In der API Beschreibung wird stdcall gemeint sein. Das fiese ist, dass pascal eigentlich die Bezeichnung für die Übergabe auf dem Stack ist. Stdcall ist eine Unterform, die die Parameter umgekehrt übergibt.
Pascal und stdcall gibt es in Delphi in dieser Form. In C gibt es aber nur cdecl und stdcall, so dass dort mit Pascal die Übergabe auf dem Stack gemeint ist, aber eben in Form der Unterform stdcall.

Stdcall wird also stimmen.
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 489
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Fr 19.06.15 12:00 
Ein freundliches Hallo an alle,

nachdem die Unsicherheit bei der CallBack einigermaßen beseitigt war, habe ich die Meldungen geprüft, die noch nicht bearbeitet wurden. Es zeigte sich, dass nach dem Trennen der Verbindung "LINECALLSTATE_ONHOLD" und dann "LINECALLSTATE_IDLE" mitgeteilt wird. Anscheinend ist "LINECALLSTATE_ONHOLD" die Ursache. Danach wird die Leitung anscheinend offen gehalten, um weitere Aktionen wie Dial durchzuführen. Lt. MS sollte dieser Status nicht auftauchen:
Zitat:
The new call state. This parameter must be one and only one of the following LINECALLSTATE_ constants.
( msdn.microsoft.com/e...20%28v=vs.85%29.aspx ). Nachdem ich nun die Leitung schließe und erneut öffne funktioniert es wie gewünscht.

Grüße von der regenrischen Nordsee

Peter
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Fr 19.06.15 14:24 
Wenn

msdn.microsoft.com/e...12%28v=vs.85%29.aspx

und

de.wikipedia.org/wiki/Aufrufkonvention

stimmt dann ist das eine umgedrehte stdcall (?):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure lineCallbackFunc(
   DWORD dwParam3,
   DWORD dwParam2,
   DWORD dwParam1,
   DWORD dwCallbackInstance,
   DWORD dwMsg,
   DWORD hDevice
); cdecl;


In einem anderen MS Artikel wurde auf die Funktion

msdn.microsoft.com/e...57%28v=vs.85%29.aspx

verwiesen.

Edit: auf wiki steht dort "cdecl + Parameter links->rechts + Funktion selber aufraemen" das sollte dann einem "stdcall + Parameter links->rechts" entsprechen, ist dort echt mies beschrieben

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
SMO
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 120
Erhaltene Danke: 18


D2005 Personal
BeitragVerfasst: Fr 19.06.15 14:58 
user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
dann ist das eine umgedrehte stdcall (?)


Das haben jaenicke und ich doch bereits geklärt. Ja, die Aufrufkonvention "pascal" (Delphi) bzw. "__pascal" (C) ist ein "umgedrehtes stdcall".
Windows 3.x (16 bit) hat das wohl auch tatsächlich benutzt. In der 32 bit Windows API findet man noch immer gelegentlich "PASCAL" Definitionen, wohl aus historischen Gründen, aber dieses "PASCAL" ist eben nicht "__pascal". In der WinAPI Headerdatei WinDef.h wird nämlich "PASCAL" als "__stdcall" definiert (gleiches gilt für WINAPI und CALLBACK).

Es stimmt also alles, die TAPI "lineCallbackFunc" ist stdcall.