digitalmars.D - cast class references to void and back
- BLS (35/35) Sep 18 2007 From the D spec;
- BLS (10/56) Sep 18 2007 Still someone out there who is still mental health ? 'cause const
- Regan Heath (4/63) Sep 18 2007 Sort of, you have a pointer to a reference to a Cwnd class object.
- BLS (6/71) Sep 18 2007 Thanks for clarification Regan.
-
Regan Heath
(27/97)
Sep 18 2007
No problem, I just hope I'm not wrong!
From the D spec; Pointer Conversions Casting pointers to non-pointers and vice versa is allowed in D, however, do not do this for any pointers that point to data allocated by the garbage collector. Given : Class CWin : CMsg { Cwin pWnd = null; // create a refrence /* C++ pWnd = reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams); */ // D probabely pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam).lpCreateParams; } The LPCREATESTRUCT from WinUser.d struct CREATESTRUCTA { LPVOID lpCreateParams; // Here I am HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; // etc. } alias CREATESTRUCTA* LPCREATESTRUCTA; So : 1) Do I have to put a cast(int) in there (where the (long) was in C++) The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. 2) I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this. 3) Following the D spec. this is also not guaranteed to work. confirm/deny ? Thanks in advance Bjoern
Sep 18 2007
BLS schrieb:From the D spec; Pointer Conversions Casting pointers to non-pointers and vice versa is allowed in D, however, do not do this for any pointers that point to data allocated by the garbage collector. Given : Class CWin : CMsg { Cwin pWnd = null; // create a refrence /* C++ pWnd = reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams); */ // D probabely pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam).lpCreateParams; } The LPCREATESTRUCT from WinUser.d struct CREATESTRUCTA { LPVOID lpCreateParams; // Here I am HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; // etc. } alias CREATESTRUCTA* LPCREATESTRUCTA; So : 1) Do I have to put a cast(int) in there (where the (long) was in C++) The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. 2) I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this. 3) Following the D spec. this is also not guaranteed to work. confirm/deny ? Thanks in advance BjoernStill someone out there who is still mental health ? 'cause const discussion :-) In this case just another question, In case that I define Class CWnd { CWnd* pWnd = 0; } Do I have then in fact CWin** (from a C++ view) ?
Sep 18 2007
BLS wrote:BLS schrieb:Sort of, you have a pointer to a reference to a Cwnd class object. Where a 'reference' is like but not exactly the same as a pointer. ReganFrom the D spec; Pointer Conversions Casting pointers to non-pointers and vice versa is allowed in D, however, do not do this for any pointers that point to data allocated by the garbage collector. Given : Class CWin : CMsg { Cwin pWnd = null; // create a refrence /* C++ pWnd = reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams); */ // D probabely pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam).lpCreateParams; } The LPCREATESTRUCT from WinUser.d struct CREATESTRUCTA { LPVOID lpCreateParams; // Here I am HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; // etc. } alias CREATESTRUCTA* LPCREATESTRUCTA; So : 1) Do I have to put a cast(int) in there (where the (long) was in C++) The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. 2) I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this. 3) Following the D spec. this is also not guaranteed to work. confirm/deny ? Thanks in advance BjoernStill someone out there who is still mental health ? 'cause const discussion :-) In this case just another question, In case that I define Class CWnd { CWnd* pWnd = 0; } Do I have then in fact CWin** (from a C++ view) ?
Sep 18 2007
Regan Heath schrieb:BLS wrote:Thanks for clarification Regan. as you can see I,ve just copied the most of your comments ... ashamed ... ,a bit ;-) Bjoern BjoernBLS schrieb:Sort of, you have a pointer to a reference to a Cwnd class object. Where a 'reference' is like but not exactly the same as a pointer. ReganFrom the D spec; Pointer Conversions Casting pointers to non-pointers and vice versa is allowed in D, however, do not do this for any pointers that point to data allocated by the garbage collector. Given : Class CWin : CMsg { Cwin pWnd = null; // create a refrence /* C++ pWnd = reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams); */ // D probabely pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam).lpCreateParams; } The LPCREATESTRUCT from WinUser.d struct CREATESTRUCTA { LPVOID lpCreateParams; // Here I am HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; // etc. } alias CREATESTRUCTA* LPCREATESTRUCTA; So : 1) Do I have to put a cast(int) in there (where the (long) was in C++) The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. 2) I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this. 3) Following the D spec. this is also not guaranteed to work. confirm/deny ? Thanks in advance BjoernStill someone out there who is still mental health ? 'cause const discussion :-) In this case just another question, In case that I define Class CWnd { CWnd* pWnd = 0; } Do I have then in fact CWin** (from a C++ view) ?
Sep 18 2007
BLS wrote:Regan Heath schrieb:No problem, I just hope I'm not wrong! <g> After reading that bit of the spec it seems that... The first and most important question is, what allocates the value assigned to lpCreateParams? Is the CREATESTRUCTA struct allocated in a call to a C function? If 'yes' then chances are the lpCreateParams value was also allocated by that C function. This raises the question, if it's a pointer to a C++ class is it compatible with D? Is it a COM class? I'm not sure how D interops with COM so I'm not much help here. What it does mean is that you should be able to cast to int and back again. However, the real question there is why was it being cast in C++ and do you need to do it in D. I don't know why but I'd guess it's related to the size of pointers in which case I believe you don't need it on D. If CREATESTRUCTA is allocated within D, and lpCreateParams is a reference to a D class then you should not cast to int, unless that class has a custom 'new': http://www.digitalmars.com/d/class.html#ClassAllocator http://www.digitalmars.com/d/class.html#ClassDeallocator which uses malloc and gc.addRange (though using gc.addRange may invalidate this, not sure). So, either way you shouldn't cast to int. In which case that piece of the spec no longer applies as LPVOID is void* (a pointer type). So, I would just use: pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam).lpCreateParams; ReganBLS wrote:Thanks for clarification Regan. as you can see I,ve just copied the most of your comments ... ashamed ... ,a bit ;-)BLS schrieb:Sort of, you have a pointer to a reference to a Cwnd class object. Where a 'reference' is like but not exactly the same as a pointer. ReganFrom the D spec; Pointer Conversions Casting pointers to non-pointers and vice versa is allowed in D, however, do not do this for any pointers that point to data allocated by the garbage collector. Given : Class CWin : CMsg { Cwin pWnd = null; // create a refrence /* C++ pWnd = reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams); */ // D probabely pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam).lpCreateParams; } The LPCREATESTRUCT from WinUser.d struct CREATESTRUCTA { LPVOID lpCreateParams; // Here I am HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; // etc. } alias CREATESTRUCTA* LPCREATESTRUCTA; So : 1) Do I have to put a cast(int) in there (where the (long) was in C++) The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. 2) I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this. 3) Following the D spec. this is also not guaranteed to work. confirm/deny ? Thanks in advance BjoernStill someone out there who is still mental health ? 'cause const discussion :-) In this case just another question, In case that I define Class CWnd { CWnd* pWnd = 0; } Do I have then in fact CWin** (from a C++ view) ?
Sep 18 2007