Re: Using a callback function name as an argument in a function
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Wed, 23 Jan 2008 00:16:29 -0500
Overall, I agree. I haven't written a "callback" method since I started using C++;
virtual methods are the best approach. If you need a callback in C++, you are probably
making fundamental design errors.
The API callbacks are truly quaint, and the worst of them don't allow passing an arbitrary
user parameter (and it shows the defective thinking that in 20 years of the API, nobody
has replaced these with an Ex version that solved this long-standing problem). They
should not be used as models of programming methodology.
As pointed out, the error message is screamingly obvious:
error C2664: 'lineInitializeExA' : cannot convert parameter 3 from 'void
(unsigned long,unsigned long,unsigned long,unsigned long,unsigned
long,unsigned long)' to 'void (__stdcall *)(unsigned long,unsigned
long,unsigned long,unsigned long,unsigned long,unsigned long)'
None of the functions with this name in scope match the target type
Look at what it says:
cannot convert from
void void
(__stdcall *)
(unsigned long, (unsigned long,
unsigned long, unsigned long,
unsigned long, to unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long,
unsigned long) unsigned long)
Is the difference not obvious? It WANTs a prototype that has __stdcall, and you gave it a
method which was NOT __stdcall!
Since it is a callback function, you should have supplied a CALLBACK (that is, __stdcall)
method in your function definition
But you should abandon the concept of callback as a way of life.
joe
On Thu, 17 Jan 2008 12:25:43 +0100, "Giovanni Dicanio" <giovanni.dicanio@xxxxxxxxxxx>
wrote:
To add to what others correctly wrote, have you considered the option ofJoseph M. Newcomer [MVP]
changing your design, making it more C++ and less C?
What IMHO could be good is to define an *interface* (C++), which a "worker"
object must implement, instead of C-style callbacks.
e.g.
// Instead of having a call-back, use a C++ interface
class ILineProcessor
{
public:
virtual ~ILineProcessor(); // virtual dtor for proper cleanup
// The job that the callback did in the previous design
virtual void DoWork( ...parameters... ) = 0;
// ... other interface methods, if needed...
};
Then you derive a concrete class which implements the above interface, and
this concrete class does the real job.
Having defined a class (and not just a C-function callback), you can store
lots of useful information, like additional status information (via private
data members), etc. The resulting code will be more robust, extensible, just
more quality.
I think that the call-backs are an old design, considering that the Win32
API is a kind of "C" framework. So, in C, call-backs are useful. But IMHO in
C++ we can use *interfaces* to get better quality code.
In fact, there are also some new APIs in Vista (about common dialogs, IIRC),
that works with COM *interfaces* (because the concept of interfaces is more
robust and more quality than C-style call-backs).
Just my 2 cents.
Giovanni
"Dan Gistenson" <d.gistenson@xxxxxxxxxxxxx> ha scritto nel messaggio
news:WDbjj.51$Rg1.38@xxxxxxxxxxxxxxxxxxxxxxx
Hi.
Can someone tell me where I'm going wrong with this problem in my vc6 mfc
sdi project, and tell me how to fix it? I understand the general meaning
of
the compiler's 2664 error message, but I don't understand what's wrong
with
my approach and how to fix it. The problem lies with argument 3 of
lineInitializeEx() and/or the prototype and definition of
lineCallbackFunc().
I used Class wizard to add the member function lineCallbackFunc() to my
doc
class. The function will be used as a callback function, by using it as
the
third argument in a call to lineInitializeEx() which I hav placed in the
OnNewDocument member function of my doc class.
The compiler error message, the prototype and definition of the callback
function, and the call to lineInitializeEx() are below, in that order.
What
am I doing wrong, and how do I fix it?
The compiler error message is:
error C2664: 'lineInitializeExA' : cannot convert parameter 3 from 'void
(unsigned long,unsigned long,unsigned long,unsigned long,unsigned
long,unsigned long)' to 'void (__stdcall *)(unsigned long,unsigned
long,unsigned long,unsigned long,unsigned long,unsigned long)'
None of the functions with this name in scope match the target type
The callback function's prototype is:
void lineCallbackFunc(DWORD hDevice, DWORD dwMsg, DWORD
dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3);
The callback function's definition is:
void CFoneIODoc::lineCallbackFunc (DWORD hDevice, DWORD dwMsg, DWORD
dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
// My code will go here.
}
Finally, the call to lineInitializeEx() is: (Argument 3 is the issue.)
lResult = lineInitializeEx( &hLineApp, NULL, lineCallbackFunc, "TAPI
App!",
&dwNumDevs, &dwHighApiVersion, &lineInit );
Please help.
Thanks,
Dan
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- Using a callback function name as an argument in a function
- From: Dan Gistenson
- Re: Using a callback function name as an argument in a function
- From: Giovanni Dicanio
- Using a callback function name as an argument in a function
- Prev by Date: Re: Can I Increase size of nNoMansLandSize?
- Next by Date: Re: Owner draw repaint
- Previous by thread: Re: Using a callback function name as an argument in a function
- Next by thread: Can I Increase size of nNoMansLandSize?
- Index(es):
Relevant Pages
|