Casting Function pointers : Can anyone correct this MS Knowledge base Example pls ?

D

Dirk Vanhaute

I have only small knowledge of c++, but I would like to compile the
example in
http://support.microsoft.com/kb/q246772/
HOWTO: Retrieve and Set the Default Printer in Windows
I included "#include <Windows.h>" at the start, and the following goes
wrong :

BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize)
{
....
PROC fnGetDefaultPrinter = NULL;
....
// This line works :
fnSetDefaultPrinter = GetProcAddress(hWinSpool, SETDEFAULTPRINTER);
....
bFlag = fnGetDefaultPrinter(pPrinterName, pdwBufferSize);
// but this one gives
// GetDfltPrt.cpp(100) : error C2197: 'int (__stdcall *)(void)' : too
many actual parameters
....
bFlag = fnSetDefaultPrinter(pPrinterName);
// and this gives the same.

This should probably be casted, because the number of parameters is
different.
Comments on this code are also welcome. Are there better ways to get
the default printer on all windows platforms ?
Many thanks in advance.
Dirk.
 
J

JKop

Dirk Vanhaute posted:
I have only small knowledge of c++, but I would like to compile the
example in
http://support.microsoft.com/kb/q246772/
HOWTO: Retrieve and Set the Default Printer in Windows
I included "#include <Windows.h>" at the start, and the following goes
wrong :

BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize)
{
...
PROC fnGetDefaultPrinter = NULL;
...
// This line works :
fnSetDefaultPrinter = GetProcAddress(hWinSpool, SETDEFAULTPRINTER);
...
bFlag = fnGetDefaultPrinter(pPrinterName, pdwBufferSize);
// but this one gives
// GetDfltPrt.cpp(100) : error C2197: 'int (__stdcall *)(void)' : too
many actual parameters
...
bFlag = fnSetDefaultPrinter(pPrinterName);


If you have a function that looks like so:

int Blah(char, int, bool);


then to define a pointer to such a *type* of function, you do:

int (*p_Blah)(char, int, bool) = Blah;


What's happening in your code is that the types don't match. It's akin to
doing the following:

void Blah(int);

char (*p_Blah)(char,bool,float) = Blah;


What you need to do is change the type of your pointer!


-JKop
 
J

John Harrison

This should probably be casted, because the number of parameters is
different.

Seems reasonable.
Comments on this code are also welcome.

It's the usual pile of shit.
Are there better ways to get
the default printer on all windows platforms ?

No idea, ask on a Windows programming group. Your question is off topic for
two different reasons, firstly the code is C not C++, secondly Windows
programming is not on topic in a C++ language group. Try
Many thanks in advance.
Dirk.

john
 
H

Howard

John Harrison said:
Seems reasonable.


It's the usual pile of shit.

Personal aversion to Windows programming expressed here? Or C-style API
calls in general?

You may not like Windows, but a lot of us have to write C++ code that runs
on that platform. And since the API is in C, we're stuck with C-style
interfaces in our C++ code.
No idea, ask on a Windows programming group. Your question is off topic
for
two different reasons, firstly the code is C not C++, secondly Windows
programming is not on topic in a C++ language group. Try

It's valid C++ code. Sure, it's calling a C API function, but if the
program is a C++ program, it's reasonable that the question could be
considered a C++ question.

The problem is apparently the definition of "PROC", which isn't shown. The
OP needs to define the function pointer to match the function declaration,
which it obviously doesn't. Simply using "PROC" is not the answer. The OP
needs to get the actual declaration of the function, and define a pointer
that matches that declaration.

However, you're right that THAT information is something the he probably
needs to go to a Windows newsgroup for, since we don't have (and don't
particularly care about) that info here.

-Howard
 
J

John Harrison

Howard said:
Personal aversion to Windows programming expressed here? Or C-style API
calls in general?

Neither, the example is typical of the poor standard of coding that exists
on MSDN. I particular I don't like the needless use of Windows specific
types (BOOL, DWORD etc) and functions (lstrlen, lstrcat etc) when perfectly
good standard alternatives exist. Also the completely gratuitous casting all
over the place.

john
 
J

JKop

John Harrison posted:
Neither, the example is typical of the poor standard of coding that
exists on MSDN. I particular I don't like the needless use of Windows
specific types (BOOL, DWORD etc) and functions (lstrlen, lstrcat etc)
when perfectly good standard alternatives exist. Also the completely
gratuitous casting all over the place.

john


Don't forget the use of ZeroMemory, plus...

typedef struct _Blah
{
int k;
} Blah;


(I think that's the syntax they use!


-JKop
 
H

Howard

JKop said:
typedef struct _Blah
{
int k;
} Blah;


(I think that's the syntax they use!

That's normal C code, isn't it? Unless C has changed is standards (which I
have no idea), then that's just a complaint about using C. (Which to my
mind is nothing to complain about...in fact, it just makes it easier to use
from a variety of languages, doesn't it?)

-Howard
 
D

Dirk Vanhaute

Howard said:
The problem is apparently the definition of "PROC", which isn't shown. The
OP needs to define the function pointer to match the function declaration,
which it obviously doesn't. Simply using "PROC" is not the answer. The OP
needs to get the actual declaration of the function, and define a pointer
that matches that declaration.

PROC is defined via windef.h as
typedef int (CALLBACK *PROC)();

and CALLBACK as
#define CALLBACK __stdcall

I thought those BOOL, DWORD ... types were something of C++. I write
a little c and use the classical types int, char, long, ...
I don't think Kernighan and Ritchie approve this kind of misuse.

Thanks to JKop, Howard and John for you help.
Dirk.
 
D

Dirk Vanhaute

Howard said:
The problem is apparently the definition of "PROC", which isn't shown. The
OP needs to define the function pointer to match the function declaration,
which it obviously doesn't. Simply using "PROC" is not the answer. The OP
needs to get the actual declaration of the function, and define a pointer
that matches that declaration.

PROC is defined via windef.h as
typedef int (CALLBACK *PROC)();

and CALLBACK as
#define CALLBACK __stdcall

I thought those BOOL, DWORD ... types were something of C++. I write
a little c and use the classical types int, char, long, ...
I don't think Kernighan and Ritchie approve this kind of misuse.

Thanks to JKop, Howard and John for you help.
Dirk.
 
K

Karl Heinz Buchegger

Dirk said:
PROC is defined via windef.h as
typedef int (CALLBACK *PROC)();

and CALLBACK as
#define CALLBACK __stdcall

I thought those BOOL, DWORD ... types were something of C++.

All of them are simple #define's which eventually lead to int, unsigned
int etc. There is no difference to C.

But Howard is right. What you need to do is to define the function
pointer correctly.

eg. You want the pointer fnSetDefaultPrinter to point to the function
that does 'Set Default Printer'. From the docu you got: it is a function
which returns an int and takes a const char* as its first parameter.
Thus it should be:

int (*fnSetDefaultPrinter)( const char*);

and not

PROC fnSetDefaultPrinter;

PROC is a standard function pointer which doesn't know about
the specifics of the function in question. It is your job to add
this information by writing a correct definition.

Note: GetProcAddress() is a function which returns a 'standard function
pointer'. If you think of it, this is very logical. GetProcAddress needs
to return any function pointer regardless of what the real function has as
return type or what arguments it takes. So you have no other choice as to
heavily cast that pointer to the desired type. You an do eg.

(*(PROC*)&fnSetDefaultPrinter = GetProcAddress( hWinSpool, SETDEFAULTPRINTER );

That is casting the left hand side of the assignment to match what GetProcAddress
returns, instead of the other way round. This way all usages of GetProcAddress look
basically the same, even if there are different types of function pointers are involved.

As for:
Are there better ways to get
the default printer on all windows platforms ?

You should ask this in a Windows newsgroup as it is definitily way off topic here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top