Callback-Function für TAPI32.DLL

Fragen rund um diverse Windows-Versionen, ihr Verhalten unter Xbase++ und den Umgang mit der API

Moderator: Moderatoren

Antworten
thomas
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 116
Registriert: Fr, 23. Sep 2005 16:07
Wohnort: Bad Oldesloe
Kontaktdaten:

Callback-Function für TAPI32.DLL

Beitrag von thomas »

Hallo,

ich würde gerne die TAPI32.DLL unter XBase++ benutzen, um eine Telefonanlage zu steuern.
Die TAPI32.DLL bietet mir die Möglichkeit alle Events der Telegonanlage per Callback-Funktion
zu erhalten. Die Callback-Funktion habe ich in C++ geschrieben und als Pointer an die TAPI32.DLL
übergeben. Nach Auslösung irgendeines Events (z.B. Telefon klinget) wird meine Callback-Funktion
von der TAPI32.DLL aufgerufen. Leider erhalte ich dann sofort die folgende Fehlermeldung.
"Exception: Zugriffsverletzung bei Adresse 004568E0 in Modul 'XPPRT1.dll'. Lesen von Adresse 00000004"
Wie ich nun feststellen musste, ist die TAPI32.DLL Multi-Threaded und generiert bei jedem Event einen
Thread, der dann meine Callback-Funktion aufruft. Sobald in meinem C-Programm die C-API Funktionen
"_conNew, _conPutNl, _conCall" von XBase++ benutzt werden, wird dieser Exception-Fehler erzeugt.
Hat jemand Erfahrung in C++ in Verbindung mit der C-API Schnittstelle von Xbase ?


#include <xppdef.h>
#include <xpppar.h>
#include <xppcon.h>
//-------------------------------------------------------------------------------------------------------------------------
VOID FAR PASCAL lineCallbackFunc(
DWORD hDevice,
DWORD dwMsg,
DWORD dwCallbackInstance,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
);
//-------------------------------------------------------------------------------------------------------------------------
XPPRET XPPENTRY LP_MYCALLBACK( XppParamList pl){ _retnl(pl, (LONG) lineCallbackFunc ); }
//-------------------------------------------------------------------------------------------------------------------------
VOID FAR PASCAL lineCallbackFunc(
DWORD hDevice,
DWORD dwMsg,
DWORD dwCallbackInstance,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3)
{
ContainerHandle conr = _conNew( NULLCONTAINER );
ContainerHandle con1 = _conPutNL( NULLCONTAINER , (LONG) hDevice );
ContainerHandle con2 = _conPutNL( NULLCONTAINER , (LONG) dwMsg );
ContainerHandle con3 = _conPutNL( NULLCONTAINER , (LONG) dwCallbackInstance );
ContainerHandle con4 = _conPutNL( NULLCONTAINER , (LONG) dwParam1 );
ContainerHandle con5 = _conPutNL( NULLCONTAINER , (LONG) dwParam2 );
ContainerHandle con6 = _conPutNL( NULLCONTAINER , (LONG) dwParam3 );
_conCall( conr , "MyCall6p" , 6, con1, con2, con3, con4, con5, con6);
_conRelease(conr);
_conRelease(con1);
_conRelease(con2);
_conRelease(con3);
_conRelease(con4);
_conRelease(con5);
_conRelease(con6);

}
//-------------------------------------------------------------------------------------------------------------------------
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo, Thomas.

Ich versuche etwas ganz Ähnliches, aber mit der BAP-Library. Die Versuche sind allerdings aus Zeitmangel versandet. In der kommenden Woche krame ich das nochmal raus und würde das dann gerne mit Dir diskutieren.
Herzlich,
Tom
thomas
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 116
Registriert: Fr, 23. Sep 2005 16:07
Wohnort: Bad Oldesloe
Kontaktdaten:

Beitrag von thomas »

Hallo Tom.

Nach diversen Versuchen mit der BAP.LIB und der Cockpit Library konnte ich das Callback-Problem auch nicht in den Griff bekommen. Immer wieder wurde dieser „Exception“ Fehler generiert. Gestern hatte ich Pablo Botella das Problem geschildert und siehe da, er konnte es auf anhieb lösen. Nochmals Danke für Deine angebotene Hilfe.

Gruß
Thomas
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo, Thomas.
Gestern hatte ich Pablo Botella das Problem geschildert und siehe da, er konnte es auf anhieb lösen.
Und wie? :wink:
Herzlich,
Tom
thomas
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 116
Registriert: Fr, 23. Sep 2005 16:07
Wohnort: Bad Oldesloe
Kontaktdaten:

Beitrag von thomas »

Hallo Tom.

Gute Frage ! Soweit ich das verstanden habe, initialisiert der TAPI32.DLL Callback-Aufruf nicht den STACK (TSP) und deshalb kamen die Exception-Fehler. Pablo hatte dann das C-Programm erweitert. Leider verstehe ich nicht viel von C++, das ich Dir das erklären könnte. Aber vielleicht kannst Du mir das erklären ?
Ich habe mein TAPI-Projekt erfolgreich beenden können und seit Gestern ist das Programm im Echtbetrieb. Mal sehen ob es die Feuertaufe übersteht, denn bisher funktioniert die Callback-Funktion rasend gut.

Code: Alles auswählen

#define MSG_LINE_CALLBACK        WM_USER + 100
#define MSG_END_LOOP             WM_USER + 101
#define MSG_SAY_HELLO            WM_USER + 102
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <xpppar.h>
#include <xppcon.h>
//-------------------------------------------------------------------------------------------------------------------------
#pragma comment(lib,"kernel32")
#pragma comment(lib,"user32")
#pragma comment(lib,"gdi32")
//-------------------------------------------------------------------------------------------------------------------------
#include "CustomMsg.ch"
#define MYHEAPFLAGS (HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY)
//-------------------------------------------------------------------------------------------------------------------------
static char szWndClassName[] = "ID_179070F5A3F843B396E91C41CEEAB84C" ; // UUID
HWND _hWnd_ = 0;
//-------------------------------------------------------------------------------------------------------------------------
static VOID FAR PASCAL lineCallbackFunc(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
static LRESULT CALLBACK _WndProc_(HWND,UINT, WPARAM, LPARAM);
//-------------------------------------------------------------------------------------------------------------------------
XPPRET XPPENTRY APPINSTANCE( XppParamList pl){ _retnl( pl,(LONG) GetModuleHandle(NULL)); }
//-------------------------------------------------------------------------------------------------------------------------
XPPRET XPPENTRY MYLOOP_QUIT( XppParamList pl)
{ 
   if( _hWnd_ != NULL ) SendMessage( _hWnd_ , MSG_END_LOOP , 0 , 0 );
   _ret(pl);
}
//-------------------------------------------------------------------------------------------------------------------------
XPPRET XPPENTRY MYLOOP_SAY_HELLO( XppParamList pl)
{ 
   if( _hWnd_ != NULL ) SendMessage( _hWnd_ , MSG_SAY_HELLO , 0 , 0 );
   _ret(pl);
}
//-------------------------------------------------------------------------------------------------------------------------
XPPRET XPPENTRY MYLOOP( XppParamList pl)
{
   MSG         msg;
   WNDCLASSEX  wndclass;

     wndclass.cbSize        = sizeof (wndclass) ;
     wndclass.style         = CS_HREDRAW;
     wndclass.lpfnWndProc   = _WndProc_ ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = (HINSTANCE) GetModuleHandle(NULL);
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szWndClassName;
     wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION);
     RegisterClassEx (&wndclass);

     _hWnd_ = CreateWindow(szWndClassName,"", WS_DISABLED , 0,0,1,1,NULL,NULL,(HINSTANCE) GetModuleHandle(NULL),NULL);
     while(GetMessage (&msg, NULL, 0, 0)) DispatchMessage (&msg) ;
     UnregisterClass(szWndClassName,(HINSTANCE) GetModuleHandle(NULL) );
     _hWnd_ = 0;
   _ret(pl);
}
//-------------------------------------------------------------------------------------------------------------------------
XPPRET XPPENTRY LP_MYCALLBACK( XppParamList pl){ _retnl(pl, (LONG) lineCallbackFunc ); }
//-------------------------------------------------------------------------------------------------------------------------
static VOID FAR PASCAL lineCallbackFunc(DWORD dw0,DWORD dw1,DWORD dw2,DWORD dw3,DWORD dw4,DWORD dw5)
{
   if( _hWnd_ != NULL )
   {
      DWORD szData[6];
      szData[0] = dw0; szData[1] = dw1; szData[2] = dw2; szData[3] = dw3; szData[4] = dw4; szData[5] = dw5;
      SendMessage( _hWnd_ , MSG_LINE_CALLBACK , 0 , (LPARAM)((void*) &szData) );
   }
}
//-------------------------------------------------------------------------------------------------------------------------
static LRESULT CALLBACK _WndProc_(HWND hWnd ,UINT nMsg ,WPARAM wp , LPARAM lp )
{

   switch( nMsg )
   {
      case MSG_LINE_CALLBACK :
      {
         DWORD * pData = (DWORD *)((void *) lp);
         ContainerHandle conr = _conNew( NULLCONTAINER );
         ContainerHandle con0 = _conPutNL( NULLCONTAINER , (LONG) pData[0]);
         ContainerHandle con1 = _conPutNL( NULLCONTAINER , (LONG) pData[1]);
         ContainerHandle con2 = _conPutNL( NULLCONTAINER , (LONG) pData[2]);
         ContainerHandle con3 = _conPutNL( NULLCONTAINER , (LONG) pData[3]);
         ContainerHandle con4 = _conPutNL( NULLCONTAINER , (LONG) pData[4]);
         ContainerHandle con5 = _conPutNL( NULLCONTAINER , (LONG) pData[5]);
         _conCall( conr , "MyCall6p" , 6, con0, con1, con2, con3, con4, con5);
         _conRelease(conr);_conRelease(con0);_conRelease(con1);_conRelease(con2);
         _conRelease(con3);_conRelease(con4);_conRelease(con5);
         return 0;
      }
      case MSG_END_LOOP:{ _hWnd_ = 0; DestroyWindow(hWnd);PostQuitMessage(0);return 0;}
      case WM_DESTROY:{PostQuitMessage(0);return 0;}
      case MSG_SAY_HELLO :
      {
         ContainerHandle conr = _conNew( NULLCONTAINER );
         ContainerHandle con = _conPutC(NULLCONTAINER , "Heeeeeeelllllllllllloooooo");
         _conCall( conr , "QOut" , 1, con);
         _conRelease(conr);_conRelease(con);
         return 0;
      }
   }
   return DefWindowProc(hWnd,nMsg,wp,lp);
}
//-------------------------------------------------------------------------------------------------------------------------
Xbase-Source:

Code: Alles auswählen

#include "dll.ch"
#include "AppEvent.ch"
REQUEST _LP_MYCALLBACK
REQUEST _MYLOOP
REQUEST _MYLOOP_QUIT
REQUEST _MYLOOP_SAY_HELLO
REQUEST QOUT
//-------------------------------------------------------------------------------------------------------------------------
static dwDeviceID  
static dwAPIVersion
static dwNull      
static dwPriv      
static dw10        
static dw12        
static lpCallParams 
static lpHLine 
//-------------------------------------------------------------------------------------------------------------------------
function main()
LOCAL cTpl
LOCAL lphLineApp  := 0
LOCAL hInstance   := _AppInstance()
LOCAL lpszAppName := "TAPI.EXE"
LOCAL lpdwNumDev  := 0
LOCAL nCallback := _LP_MYCALLBACK()
local nEvent, mp1:= NIL, mp2 := NIL , oXbp := NIL

Thread():New():Start("_MYLOOP")

_MYLOOP_SAY_HELLO()
cTpl := DllprepareCall("tapi32.dll",DLL_STDCALL,"lineInitialize")
DllExecuteCall(cTpl,@lphLineApp,hInstance,nCallback,lpszAppName,@lpdwNumDev)
_MYLOOP_SAY_HELLO()

dwDeviceID   := 0x00000009
dwAPIVersion := 0x00020000
dwNull       := 0x00000000
dwPriv       := 0x00000002
dw10         := 0x00000010
dw12         := 0x00000012
lpCallParams := 0x00000000
lpHLine := 0
cTpl := DllprepareCall("tapi32.dll",DLL_STDCALL,"lineOpen")
DllExecuteCall(cTpl,lphLineApp,dwDeviceID,@lpHLine,dwAPIVersion,dwNull,dwNull,dwPriv,dw12,lpCallParams)
DO WHILE .T.
    nEvent := AppEvent( @mp1, @mp2, @oXbp )
    oXbp:handleEvent( nEvent, mp1, mp2 )
    DO CASE
    CASE nEvent == xbeK_ESC
        EXIT
    ENDCASE
ENDDO

cTpl := DllprepareCall("tapi32.dll",DLL_STDCALL,"lineClose")
DllExecuteCall(cTpl,lphLine)
cTpl := DllprepareCall("tapi32.dll",DLL_STDCALL,"lineShutdown")
DllExecuteCall( cTpl, lphLineApp )
_MYLOOP_QUIT()
RETURN(.T.)
//-------------------------------------------------------------------------------------------------------------------------


FUNCTION MyCall6p(a1,a2,a3,a4,a5,a6)
? a1
? a2
? a3
? a4
? a5
? a6
RETURN(NIL)
Gruß
Thomas
Antworten