Re: forwards declarations!
Hello Barry,
Boy! Function pointers used this way are not easy for me!
LRESULT callerFunction(LRESULT (*WNDPROC) (HWND, long, WPARAM, >>LPARAM), HWND
h, long m, int w, int l);
AND HERE YOU SHOOT YOURSELF IN THE FOOT BY TRYING TO USE IT AS THE
NAME OF A PARAMETER. VC will recognize this as an extension but your
compiler obviously doesn't.
I am drawing a blank ! So what is supposed to replace (*WNDPROC) ?
Your compiler does not like using the same name for a type and an
object.
I tried renaming the "(*WNDPROC)"s (the declaration one and the
implementation one) to something else but I get the same error?
Get out of the habit of using all caps for object and function names.
Reserve it for types and macro names.
I have alot to change in my coding habits and will do it eventually. Right
now I want the project to advance and as soon as I have a chance I will apply
naming convention rules as reccomended. One step at a time!
I get 7 warnings. Maybe you need to adjust your options.
Okay, well I had forgotten the principles of function pointers due to all
this double compiler catastrophy! And so its good that you did refresh my
memory. So I did manage to get rid of the warnings and now VC compiles
without errors or warnings. Amen!
======================================
Now, the declarations are:
LRESULT KWP(HWND x, long m, WPARAM w, LPARAM l);
//CALLBACK FUNCTION
LRESULT callerFunction(LRESULT (*WNDPROC) (HWND, long, WPARAM, LPARAM), HWND
h, long m, WPARAM w, LPARAM l);
and the implementations are:
LRESULT callerFunction(LRESULT(*WNDPROC)(HWND, long, WPARAM, LPARAM) ,HWND
h, long m, WPARAM w, LPARAM l)
{ return WNDPROC(h, m, w, l);
}
LRESULT KWP(HWND x, long m, WPARAM w, LPARAM l)
{
int y;
switch(m)
{
case 1000:
y = 22;
return 0;
}
//return ULC_KERNEL_DefWindowProc(hwnd, m, w, l);
return 0;
}
========================================
So that solves the code in VC++. When brought into the PIC C compiler,
because of the changes made above, I now only get 32 errors instead of 60.
Still reamians the issue of the declarations at compile time as constants
that it complains so much about.
I did try:
===========================
void ULC_KERNEL_dispatch_message ( KM_MSG *K)
{
int i=0;
LRESULT zzz;
HWND h;
WND * pwnd;
h = K->hwnd;
pwnd = h.handle;
zzz = callerFunction( pwnd->lpfnWndProc, K->hwnd, K->msg, K->wParam ,
K->lParam );
}
==============================================
But no luck I still get the same error as I posted earlier which
says "expecting an identifier" and the compiler is highlighting the second
round parenthesis "(" from the left in the declaration of the following
caller function:
LRESULT callerFunction(LRESULT (*WNDPROC) (HWND, long, WPARAM, LPARAM), HWND
h, long m, WPARAM w, LPARAM l);
In anycase, the problem here is that I learned easy samples using function
pointers and went straight to using function pointers being assinged from a
pointer stored in another structure and along with the typedefing and so
forth. Not quite the same as straight forwards function pointer usage. For me
anyways! And then this compiler discrepency.... ooff!
As I told Giovanni, if you have any other observations as to simplify the
code for the callerFunction so the PIC C compiler can handle it, it would be
very much appreciated.
Thankyou all for your help!
--
Best regards
Roberto
"Barry Schwarz" wrote:
On Sat, 10 Jan 2009 20:07:00 -0800, Robby
<Robby@discussions.microsoft.com> wrote:
Well... Okay!
At this point I think its better I provide a complete sample code. Perhaps a
little shorter than what you have read in my earlier post topics. This way it
will be easier to compare our notes. This is the code sample I actually sent
to the compiler vendor.
==========================================kernel.h
typedef long *LRESULT;
typedef long WPARAM;
typedef long LPARAM;
typedef struct tagHwnd{
void *handle;
} HWND;
typedef LRESULT (*WNDPROC)(HWND, long, WPARAM, LPARAM);
This is the start of one problem. From this point on, WNDPROC is
known as a type.
typedef struct tagWnd{
WNDPROC lpfnWndProc;
Here you use it correctly as a type.
int style;
long backGround;
long titleMsg;
long extra;
} WND, *pWND;
typedef struct tagRwp{
HWND hwnd;
int showWinEnable;
} RWP;
typedef struct tagMsg{
HWND hwnd;
long msg;
WPARAM wParam;
LPARAM lParam;
long time;
} KM_MSG, *pKM_MSG;
RWP rwp[3] = {0,0,0,0,0,0};
long ULC_KERNEL_get_msg (KM_MSG *K);
void ULC_KERNEL_dispatch_message ( KM_MSG *K);
=================================kernel.c
#include <stdio.h>
#include <KERNEL.h>
LRESULT KWP(HWND x, long m, int w, int l);
LRESULT callerFunction(LRESULT (*WNDPROC) (HWND, long, WPARAM, LPARAM), HWND
h, long m, int w, int l);
AND HERE YOU SHOOT YOURSELF IN THE FOOT BY TRYING TO USE IT AS THE
NAME OF A PARAMETER. VC will recognize this as an extension but your
compiler obviously doesn't.
void main()
{
KM_MSG MESSAGE;
Get out of the habit of using all caps for object and function names.
Reserve it for types and macro names.
WND wnd;
// DEFINE A WINDOW!
wnd.lpfnWndProc = KWP;
wnd is an object of type WND which is the same as struct tagWnd. The
member lpfnWndProc of that struct is defined as an object of type
WNDPROC which is the same as
pointer to function
returning LRESULT (also known as long*)
and taking arguments of type
HWND (also known as struct tagHwnd)
long
WPARAM (also known as long)
LPARAM (also known as long)
You try to assign this pointer the value KWP. KWP is defined as
address of function
returning LRESULT (also known as long)
and taking arguments of type
HWND (also known as struct tagHwnd)
long
int
int
Notice that the third and forth arguments are of different types, the
pointer expecting two of type long and the function expecting two of
type int. Even though there is an implicit conversion between int and
long in either direction, THERE IS NO IMPLICIT CONVERSION BETWEEN
FUNCTION POINTERS TAKING THESE TYPES AS ARGUMENTS. You can cast the
value KWP to match the type of lpfnWndProc but that is a bad idea
because if you actually call KWP through this pointer the behavior
becomes undefined. (The code that performs the call will insure that
the two arguments are of type long but the function KWP will attempt
to process them as type int.)
wnd.style = 0;
wnd.backGround = 0;
wnd.titleMsg = 0;
wnd.extra = 0;
while(ULC_KERNEL_get_msg(&MESSAGE))
{
ULC_KERNEL_dispatch_message(&MESSAGE);
}
}
long ULC_KERNEL_get_msg (KM_MSG *K)
{
K->msg = 1;
return K->msg;
}
void ULC_KERNEL_dispatch_message ( KM_MSG *K)
{
int i=0;
LRESULT zzz;
HWND h = K->hwnd;
WND * pwnd = (WND *)(h.handle);
zzz = callerFunction( pwnd->lpfnWndProc, K->hwnd, K->msg, K->wParam ,
K->lParam );
}
//CALLBACK FUNCTION
LRESULT callerFunction(LRESULT(*WNDPROC)(HWND, long, WPARAM, LPARAM) ,HWND
h, long m, int w, int l)
{ return WNDPROC(h, m, w, l);
}
LRESULT KWP(HWND x, long m, int w, int l)
{
int y;
switch(m)
{
case 1000:
y = 22;
return 0;
}
//return ULC_KERNEL_DefWindowProc(hwnd, m, w, l);
return 0;
}
=========================================
Giovanni.... one thing, in the sample code above, I never innitialized the
handler pointer member of the tagHwnd structure. In the previous post topics
version I do innitalize it... but for now to render the code as small as
possible I ignored it. This should not be relevent to the problem here...
since all I want to try to do for now is compile the code without errors.
Also the ULC_KERNEL_get_msg() and the ULC_KERNEL_dispatch_message() functions
are really irrelivent too.
I have so many versions of this problem that I am forgetting which samples I
am posting in this community versus the samples I am posting in the
compiler's specific forum. I also am keeping track of the samples I am
sending to the vendor...But for now lets concentrate on the above sample....
all to say that in one of the previous samples there was one version that
compiled error/warning free in VC++... but now the sample above has changed a
little and now compiles without errors but with 2 warnings in VC++. The
I get 7 warnings. Maybe you need to adjust your options.
warnings are the following:
c:\dts_visual_c++\yyy\yyy\kernel.c(17) : warning C4028: formal parameter 3
different from declaration
c:\dts_visual_c++\yyy\yyy\kernel.c(17) : warning C4028: formal parameter 4
different from declaration
and for both warnngs VC++ points to this line ????:
wnd.lpfnWndProc = KWP;
Concerning these two warnings, what does the 3rd and 4th parameter have to
do with being different from the declaration... which declaration? I don't
understand what the warnings are trying to say !!! Anyways can you see why I
am getting these two warnings?
The object being assigned a value must have the same or compatible
type as the expression which denotes the value. These don't meet this
requirement.
As for the PIC C compiler I get the same error as I posted earlier which
says "expecting an identifier" and the compiler is highlighting the second
round parenthesis "(" from the left in the declaration of the following
caller function:
Your compiler does not like using the same name for a type and an
object.
LRESULT callerFunction(LRESULT (*WNDPROC) (HWND, long, WPARAM, LPARAM), HWND
h, long m, int w, int l);
Also the above code when compiled in the PIC C compiler, generates errors at
the next two lines. The errors are "Expression must evaluate to a constant".
HWND h = K->hwnd;
WND * pwnd = (WND *)(h.handle);
Apparently with your reduced capability compiler, initialization
values must be compile time constants. VC doesn't complain about
this. The simple solution appears to be to change the initialization
to an assignment:
HWND h;
WND * pwnd;
h = K->hwnd;
pwnd = h.handle; /* since h.handle is a void* and pwnd is an
object pointer, there exists an implicit conversion between them */
--
Remove del for email