X-Post: dk.edb.programmering.c
X-Post: dk.edb.programmering.java
Hej!
Jeg sidder og roder med en Java applikation der via JNI loader en (C++)
DLL og kalder funktioner i denne.
Nu ligger det sådan at jeg ønsker at modtage events i Java, fra DLL'en.
Jeg har da også etableret en java
metode der kan kaldes fra DLL'en uden problemer.
Men, men - de events jeg skal videresende til java genereres ikke af
DLL'en, men af en stand-alone EXE
fil også skrevet i C++.
Udfordringen er altså, at jeg skal:
1. Starte javaprogrammet
2. ...som loader DLL'en...
3. ...som starter standalone EXE filen...
4. DLL'en skal nu modtage events fra standalone applikationen
Step 1-3 klares fint, men jeg har lidt problemer med at etablere kontakt
mellem DLL'en og EXE filen der startes.
Jeg har forsøgt (uden held) at lave DLL'en så den 'deles' af Java og
standalone applikationen.
Nu forsøger jeg mig med DDE således, at DLL'en etablerer en DDE server
som standalone applikationen kan 'snakke' til.
-Heller ikke dette ser dog ud til at fungere
Nu sidder jeg så og er lidt i tvivl om, om der er en bedre måde at
griber kommunikationen an på -
om man på en simpel måde kan etablere noget med pipes og threads der
læser på disse?
Dvs. hvis der er nogle der har styr på DDE må de meget gerne kigge på
nedenstående kode ELLER hvis der
er nogle der har styr på threads+pipes må de meget gerne poste et
simpelt eksempel.
Venlig hilsen,
Claus Bernth
---------------------------------------------------
------------ (C++) DDE kode fra DLL'en ------------
---------------------------------------------------
Fra program header:
===================
// DDE Environment Variables
// -------------------------
static PROCESS_INFORMATION pi;
static STARTUPINFO sui;
static DWORD idInst = 0; // DDEML instance object
static HCONVLIST hConvList = 0; // list of open conversations
static UINT hFormat; // handle for transaction format
static UINT DataOut,DataIn;
// Other Global Environment Variables
// ----------------------------------
static char szAppTitle[] = "WAI";
Fra init metoden:
=================
// Initialize DDE for STrayDemo event handling
DebugPrint(false, "Initialize DDE");
long rc;
rc = DdeInitialize( &idInst, (PFNCALLBACK) DdeCallback,
APPCLASS_STANDARD | // Register as standard (non-monitoring)
DDEML application
MF_CONV | // Receive notification when conversation is
established / terminated
MF_ERRORS, // Receive notification whenever a DDE error occurs
0);
if (DebugPrint((rc != DMLERR_NO_ERROR), "DDE: DdeInitialize()"))
return false;
//=== initialize string handle(s) for later lookups
hszAppName = DdeCreateStringHandle( idInst, szAppTitle, 0 );
if (DebugPrint((hszAppName == 0L), "DDE: DdeCreateStringHandle()"))
return false;
//=== register format(s)
hFormat = RegisterClipboardFormat( szAppTitle );
if (DebugPrint((hFormat == 0), "DDE: RegisterClipboardFormat()"))
return false;
HDDEDATA hddeRes = DdeNameService( idInst, hszAppName, 0, DNS_REGISTER
);
if (DebugPrint((hddeRes == 0L), "DDE: DdeNameService()"))
return false;
Min Callback funtion:
=====================
HDDEDATA CALLBACK DdeCallback( WORD wType, WORD wFmt,
HCONV hConv, HSZ hszTopic,
HSZ hszItem, HDDEDATA hData,
DWORD lData1, WORD lData2 )
{
LPCTSTR pszExec;
DWORD dwSize;
int eventNumber;
printf("DDE eventhandler...\n");
switch( wType )
{
case XTYP_CONNECT:
return (HDDEDATA)TRUE;
case XTYP_ADVREQ:
case XTYP_REQUEST:
return( DdeCreateDataHandle( idInst, (PBYTE) &DataOut,
sizeof( DataOut ), 0,
hszAppName, hFormat, 0 ) );
case XTYP_ADVSTART:
return (HDDEDATA)( wFmt == hFormat && hszItem == hszAppName );
case XTYP_ADVDATA:
if( DdeGetData( hData, (PBYTE) &DataIn, sizeof(DataIn), 0 ) )
DdeSetUserHandle( hConv, QID_SYNC, DataIn );
return (HDDEDATA)DDE_FACK;
case XTYP_EXECUTE:
DebugPrint(false, "DDE command received");
pszExec = (char*)DdeAccessData( hData, &dwSize );
//=== IMPORTANT = WIN98/95 versions require a four byte correction to
the //
//=== string address returned by the DdeAccessData function;
//
//=== WINNT versions do not require this correction. //
if( pszExec[0] <= 0x20 )
pszExec += 4;
if( pszExec )
{
eventNumber = atoi(pszExec);
TriggerJavaEvent(eventNumber);
}
break;
case XTYP_DISCONNECT:
break;
case XTYP_REGISTER:
hConvList = DdeConnectList( idInst, hszAppName, hszAppName,
hConvList, NULL );
PostTransaction( NULL, 0, XTYP_ADVSTART );
return (HDDEDATA)TRUE;
}
return( FALSE );
}
---------------------------------------------------
------------ (C++) DDE kode fra EXE'en ------------
---------------------------------------------------
Fra init metoden:
=================
// Initialize DDE for STrayDemo event handling
DdeInitialize( &idInst, (PFNCALLBACK) DdeCallback,
APPCMD_FILTERINITS | // limit (filter) msgs
CBF_SKIP_CONNECT_CONFIRMS | // don't confirm connections
CBF_FAIL_SELFCONNECTIONS | // no self-connection
CBF_FAIL_POKES, // fail XTYP_POKEs
0 );
//=== initialize string handle(s) for later lookups
char szAppSrv[] = "WAI";
static HSZ hszSrvName;
hszSrvName = DdeCreateStringHandle( idInst, szAppSrv, 0 );
hConvList = DdeConnectList( idInst, hszSrvName, hszSrvName, hConvList,
NULL );
Min Callback funtion:
=====================
HDDEDATA CALLBACK DdeCallback( WORD wType, WORD wFmt,
HCONV hConv, HSZ hszTopic,
HSZ hszItem, HDDEDATA hData,
DWORD lData1, WORD lData2 )
{
switch( wType )
{
printf("DDE: SysTrayDemo.exe\n");
case XTYP_CONNECT:
return (HDDEDATA)TRUE;
case XTYP_ADVREQ:
case XTYP_REQUEST:
return( DdeCreateDataHandle( idInst, (PBYTE) &DataOut,
sizeof( DataOut ), 0,
hszAppName, hFormat, 0 ) );
case XTYP_ADVSTART:
return (HDDEDATA)( wFmt == hFormat && hszItem == hszAppName );
case XTYP_ADVDATA:
if( DdeGetData( hData, (PBYTE) &DataIn, sizeof(DataIn), 0 ) )
DdeSetUserHandle( hConv, QID_SYNC, DataIn );
return (HDDEDATA)DDE_FACK;
case XTYP_EXECUTE:
break;
case XTYP_DISCONNECT:
break;
case XTYP_REGISTER:
hConvList = DdeConnectList( idInst, hszAppName, hszAppName,
hConvList, NULL );
// PostTransaction( NULL, 0, XTYP_ADVSTART );
return (HDDEDATA)TRUE;
}
return( FALSE );
}
|