I got a OPC client DLL, which connect to OPC servers, I use functions from the OPC client DLL via a header.
This is the typedef for the function pointers in the DLL header:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
// HDAERRORPROC
// Signals the application when an error is detected by the dll. If this callback
// is not used errors will generate a modal MessageBox which must be acknowledged
// by the user)
// prototype for the callback function is as follows:
// void CALLBACK EXPORT ErrorMsgCallback (DWORD hResult, char *pMsg)
// (the buffer supplied by the dll as pMsg is a temporary and data should be
// copied to a permanant buffer by the application)
// HDASHUTDOWNPROC
// Signals the application if the connected server requests a disconnect;
// The HANDLE parameter in the shutdown callback procedure identifies the connection.
// HDAEVENTMSGPROC
// Establishes a callback to the application for displaying
// Debug DCOM Event Messages. A character buffer is returned as a parameter
// that contains a textual description of the message.
//
//
#ifdef STRICT
typedef VOID (CALLBACK* HDAERRORPROC)(DWORD, CHAR*);
typedef VOID (CALLBACK* HDASHUTDOWNPROC)(HANDLE);
typedef VOID (CALLBACK* HDAEVENTMSGPROC)(CHAR*);
#else /* !STRICT */
|
I can avoid error popup boxes by implementing some callback functions. and sending the adresses of the callbacks functions into the DLL functions below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
//
// EnableHDAErrorNotification(...)
//
// Establishes a callback function in the user application which will receive
// control when an error is detected by the dll. If this callback is not used
// errors will generate a modal MessageBox which must be acknowledged by the user)
//
// prototype for the callback function is as follows:
// void CALLBACK EXPORT HDAErrorMsgCallback (DWORD hResult, char *pMsg)
// (the buffer supplied by the dll as pMsg is a temporary and data should be
// copied to a permanant buffer by the application)
//
_declspec(dllexport) BOOL WINAPI EnableHDAErrorNotification (HDAERRORPROC lpCallback);
//
// EnableHDAShutdownNotification(...)
//
// Establishes a callback to the application if the connected
// server requests a disconnect;
//
_declspec(dllexport) BOOL WINAPI EnableHDAShutdownNotification (HANDLE hConnect, HDASHUTDOWNPROC lpCallback);
//
// EnableHDAEventMsgs(...)
//
// Establishes a callback to the application for displaying
// Debug DCOM Event Messages
//
_declspec(dllexport) BOOL WINAPI EnableHDAEventMsgs (HDAEVENTMSGPROC lpCallback);
|
I am supposed to send 3 function pointers of the above typedefs into these functions. This I managed fine with static/non member functions. However most of the datarequests etc are implemented in a class OpcHdaDataprovider. To be able to handle a server shutdown a solution was that I made a static OpcHdaDataProvider::KeepAlive() function. This also resulted in all the class maps, vectors etc had to be static. As far as I remember static=bad, so I have tried different ways of sending member function pointers into the above functions but no luck.
The callback functions defined in OpcHdaDataProvider.h:
1) When I mouseover the code in VS2008 it always shows returntype as int not void, any idea why?
1 2 3
|
void CALLBACK EXPORT OPCShutdownCallback(HANDLE hConnect);
void CALLBACK EXPORT ErrorMsgCallback(DWORD hResult, char *pMsg);
void CALLBACK EXPORT HDAEventMsgCallback (char *Msg);
|
When I try to create a member function pointer like this:
|
HDAEVENTMSGPROC a = &OpcHdaDataProvider::HDAEventMsgCallback;
|
Gives the error:
Error 2 error C2440: 'initializing' : cannot convert from 'void (__stdcall OpcHdaDataProvider::* )(char *)' to 'HDAEVENTMSGPROC'
|
Also tried
1 2
|
void (CALLBACK EXPORT OpcHdaDataProvider::*events2)(char *) = &OpcHdaDataProvider::HDAEventMsgCallback;
setupOK = EnableHDAEventMsgs(events2) != 0;
|
error C2664: 'EnableHDAEventMsgs' : cannot convert parameter 1 from 'void (__stdcall OpcHdaDataProvider::* )(char *)' to 'HDAEVENTMSGPROC'
|
And quite a lot of other ways. After some time my guess is that this would work if the typedef was initially:
typedef VOID (CALLBACK OpcHdaDataProvider::*HDAEVENTMSGPROC)(CHAR*);
But I cant change the typedef and I have to use a class.
2) How can I make this work, assuming it is possible?