www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - C++ cast to D cast again :)

reply BLS <nanali nospam-wanadoo.fr> writes:
Hi and sorry about picking on your nerves again  :(
// C++
class CWin
{
//
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
LPARAM lParam)
{
   CWin* pWnd=NULL;  // init pWnd
}

// later ...
CWin* pChild=reinterpret_cast<CWin*>((HWND)
::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT )lParam)->CtlID) 
),GWL_USERDATA) );


}

//our D class
class CWin
{
static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam)
{
   CWin pWnd=null;  // init pWnd as    ---reference !
}
/* instead of :
CWin* pChild=reinterpret_cast<CWin*>
we use
CWin pChild = cast(CWin) cast(void*)

But I am not sure how to translate :
((HWND)
::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT )lParam)->CtlID) 
),GWL_USERDATA) );
*/

// Later we have
if (HIWORD(pWnd))

/*Since we are working with a ref. instead of a pointer this will not work.
I guess I can use :
*/

if (HIWORD(cast(void*)pWnd))
// can you confirm
}

GetWindowLong() is a Windows Api func., sure you know it.
So what the correct translation ?
Bjoern
Beside, I still wonder : Having a class A, Is A* pA a legal construct in D.
What is pA from a technical view; a pointer to a reference ?
Sep 30 2007
next sibling parent reply downs <default_357-line yahoo.de> writes:
BLS wrote:
 Beside, I still wonder : Having a class A, Is A* pA a legal construct in D.
 What is pA from a technical view; a pointer to a reference ?

Yes, and yes. :) --downs
Sep 30 2007
parent BLS <nanali nospam-wanadoo.fr> writes:
downs schrieb:
 BLS wrote:
 Beside, I still wonder : Having a class A, Is A* pA a legal construct in D.
 What is pA from a technical view; a pointer to a reference ?

Yes, and yes. :) --downs

weird.. How to deref. this stuff. ------ still hope someone is able to solve my C++ cast to D cast problem. Bjoern
Sep 30 2007
prev sibling parent reply div0 <div0 users.sourceforge.net> writes:
BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }
 
 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT )lParam)->CtlID) 
 ),GWL_USERDATA) );
 
 
 }
 
 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)
 
 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT )lParam)->CtlID) 
 ),GWL_USERDATA) );
 */
 
 // Later we have
 if (HIWORD(pWnd))
 
 /*Since we are working with a ref. instead of a pointer this will not work.
 I guess I can use :
 */
 
 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }
 
 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal construct in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong. You'll have to either allocation your cwin objects outside the garbage collectors control or pin the objects. (Don't know how you do this, depends on whether you are using phobos or tango) You should probably look at how dfl interfaces with the Win32 API, http://www.dprogramming.com/dfl.ph as that library has solved these issues and you should be able to work out how it's doing all the necessary casting/pinning.
Sep 30 2007
parent reply BLS <nanali nospam-wanadoo.fr> writes:
div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this will not 
 work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal construct 
 in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the garbage 
 collectors control or pin the objects. (Don't know how you do this, 
 depends on whether you are using phobos or tango)
 

Tango. What means "pin the object", please explain. Bjoern
 You should probably look at how dfl interfaces with the Win32 API, 
 http://www.dprogramming.com/dfl.ph as that library has solved these 
 issues and you should be able to work out how it's doing all the 
 necessary casting/pinning.

Sep 30 2007
parent reply div0 <div0 users.sourceforge.net> writes:
BLS wrote:
 div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM 
 lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this will not 
 work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal construct 
 in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the garbage 
 collectors control or pin the objects. (Don't know how you do this, 
 depends on whether you are using phobos or tango)

Tango. What means "pin the object", please explain. Bjoern

Marks the object as not movable. It looks like getAttr/setAttr is what you want, but I've not used it myself so don't blame me if your program crashes. ;) http://www.dsource.org/projects/tango/browser/trunk/lib/common/tango/core/Memory.d
 
 You should probably look at how dfl interfaces with the Win32 API, 
 http://www.dprogramming.com/dfl.ph as that library has solved these 
 issues and you should be able to work out how it's doing all the 
 necessary casting/pinning.


Sep 30 2007
parent reply div0 <div0 users.sourceforge.net> writes:
div0 wrote:
 BLS wrote:
 div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM 
 lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this will 
 not work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal 
 construct in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the 
 garbage collectors control or pin the objects. (Don't know how you do 
 this, depends on whether you are using phobos or tango)

Tango. What means "pin the object", please explain. Bjoern

Marks the object as not movable. It looks like getAttr/setAttr is what you want, but I've not used it myself so don't blame me if your program crashes. ;) http://www.dsource.org/projects/tango/browser/trunk/lib/common tango/core/Memory.d
 You should probably look at how dfl interfaces with the Win32 API, 
 http://www.dprogramming.com/dfl.ph as that library has solved these 
 issues and you should be able to work out how it's doing all the 
 necessary casting/pinning.



And to actually answer your original question: class CWin { int m_a; this() { } } extern(Windows){ typedef void* HWND; int GetWindowLongA(HWND wnd, int indx); int GetWindowLongW(HWND wnd, int indx); } void main() { // do the call (assume mbcs not unicode) int r = GetWindowLongA(cast(HWND)0, 0); // do the call & cast to CWin object pointer CWin *pWin = cast(CWin*)GetWindowLongA(cast(HWND)0, 0); Stdout( r ); } Replace the 0's with the appropriate values, ie the window handle and GWL_USERDATA (which is -21) compile with: dmd main.d user32.lib
Sep 30 2007
parent reply BLS <nanali nospam-wanadoo.fr> writes:
div0 schrieb:
 div0 wrote:
 BLS wrote:
 div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM 
 lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this will 
 not work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal 
 construct in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the 
 garbage collectors control or pin the objects. (Don't know how you 
 do this, depends on whether you are using phobos or tango)

Tango. What means "pin the object", please explain. Bjoern

Marks the object as not movable. It looks like getAttr/setAttr is what you want, but I've not used it myself so don't blame me if your program crashes. ;) http://www.dsource.org/projects/tango/browser/trunk/lib/common tango/core/Memory.d
 You should probably look at how dfl interfaces with the Win32 API, 
 http://www.dprogramming.com/dfl.ph as that library has solved these 
 issues and you should be able to work out how it's doing all the 
 necessary casting/pinning.



And to actually answer your original question: class CWin { int m_a; this() { } } extern(Windows){ typedef void* HWND; int GetWindowLongA(HWND wnd, int indx); int GetWindowLongW(HWND wnd, int indx); } void main() { // do the call (assume mbcs not unicode) int r = GetWindowLongA(cast(HWND)0, 0); // do the call & cast to CWin object pointer CWin *pWin = cast(CWin*)GetWindowLongA(cast(HWND)0, 0); Stdout( r ); } Replace the 0's with the appropriate values, ie the window handle and GWL_USERDATA (which is -21) compile with: dmd main.d user32.lib

We, means Bill B., Regan H., Jarret B. and me have discussed the C++ casting to D custing stuff a few days ago. Unfortunately our results regarding translating reinterpret_cast<CWin*> are different. Maybe we are wrong :( ... Please have a look at : http://www.prowiki.org/wiki4d/wiki.cgi?PortingFromCxx Of course! your comments are welcome. Bjoern Beside it is this part : pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT ))lParam)->CtlID which makes me banging my head on the keyboard ;)
Oct 01 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BLS wrote:
 div0 schrieb:
 div0 wrote:
 BLS wrote:
 div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM 
 wParam, LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM 
 lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this will 
 not work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal 
 construct in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the 
 garbage collectors control or pin the objects. (Don't know how you 
 do this, depends on whether you are using phobos or tango)

Tango. What means "pin the object", please explain. Bjoern

Marks the object as not movable. It looks like getAttr/setAttr is what you want, but I've not used it myself so don't blame me if your program crashes. ;) http://www.dsource.org/projects/tango/browser/trunk/lib/common tango/core/Memory.d
 You should probably look at how dfl interfaces with the Win32 API, 
 http://www.dprogramming.com/dfl.ph as that library has solved these 
 issues and you should be able to work out how it's doing all the 
 necessary casting/pinning.



And to actually answer your original question: class CWin { int m_a; this() { } } extern(Windows){ typedef void* HWND; int GetWindowLongA(HWND wnd, int indx); int GetWindowLongW(HWND wnd, int indx); } void main() { // do the call (assume mbcs not unicode) int r = GetWindowLongA(cast(HWND)0, 0); // do the call & cast to CWin object pointer CWin *pWin = cast(CWin*)GetWindowLongA(cast(HWND)0, 0); Stdout( r ); } Replace the 0's with the appropriate values, ie the window handle and GWL_USERDATA (which is -21) compile with: dmd main.d user32.lib

We, means Bill B., Regan H., Jarret B. and me have discussed the C++ casting to D custing stuff a few days ago. Unfortunately our results regarding translating reinterpret_cast<CWin*> are different. Maybe we are wrong :( ... Please have a look at : http://www.prowiki.org/wiki4d/wiki.cgi?PortingFromCxx

I don't think there's anything wrong with cast(T)(cast void*) as a replacement for C's reinterpret_cast<T> -- ignoring any larger context. The issue that div0 is talking about is more global. If you're not storing your class pointers as class pointers anywhere then the garbage collector might not realize there are still live references and collect the thing prematurely.
 Of course! your comments are welcome.
 Bjoern
 Beside it is this part :
 pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT ))lParam)->CtlID
 
 which makes me banging my head on the keyboard ;)

looks like just pWnd.GetDlgItem( (cast(LPDRAWITEMTRUCT)lParam).CtlID ) what's the confusion? --bb
Oct 01 2007
parent reply BLS <nanali nospam-wanadoo.fr> writes:
Bill Baxter schrieb:
 BLS wrote:
 div0 schrieb:
 div0 wrote:
 BLS wrote:
 div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM 
 wParam, LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM 
 lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this will 
 not work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal 
 construct in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the 
 garbage collectors control or pin the objects. (Don't know how you 
 do this, depends on whether you are using phobos or tango)

Tango. What means "pin the object", please explain. Bjoern

Marks the object as not movable. It looks like getAttr/setAttr is what you want, but I've not used it myself so don't blame me if your program crashes. ;) http://www.dsource.org/projects/tango/browser/trunk/lib/common tango/core/Memory.d
 You should probably look at how dfl interfaces with the Win32 API, 
 http://www.dprogramming.com/dfl.ph as that library has solved 
 these issues and you should be able to work out how it's doing all 
 the necessary casting/pinning.



And to actually answer your original question: class CWin { int m_a; this() { } } extern(Windows){ typedef void* HWND; int GetWindowLongA(HWND wnd, int indx); int GetWindowLongW(HWND wnd, int indx); } void main() { // do the call (assume mbcs not unicode) int r = GetWindowLongA(cast(HWND)0, 0); // do the call & cast to CWin object pointer CWin *pWin = cast(CWin*)GetWindowLongA(cast(HWND)0, 0); Stdout( r ); } Replace the 0's with the appropriate values, ie the window handle and GWL_USERDATA (which is -21) compile with: dmd main.d user32.lib

We, means Bill B., Regan H., Jarret B. and me have discussed the C++ casting to D custing stuff a few days ago. Unfortunately our results regarding translating reinterpret_cast<CWin*> are different. Maybe we are wrong :( ... Please have a look at : http://www.prowiki.org/wiki4d/wiki.cgi?PortingFromCxx

I don't think there's anything wrong with cast(T)(cast void*) as a replacement for C's reinterpret_cast<T> -- ignoring any larger context. The issue that div0 is talking about is more global. If you're not storing your class pointers as class pointers anywhere then the garbage collector might not realize there are still live references and collect the thing prematurely.

Well, http://www.digitalmars.com/d/memory.html offers some ideas I don't understand. the docs are , in this case, too nitty gritty. qze!lra"lmirmglerhmohmj Beeing really nagged and not far away from deleting all D related stuff.
 Of course! your comments are welcome.
 Bjoern
 Beside it is this part :
 pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT ))lParam)->CtlID

 which makes me banging my head on the keyboard ;)

looks like just pWnd.GetDlgItem( (cast(LPDRAWITEMTRUCT)lParam).CtlID ) what's the confusion? --bb

For sure, C++ is not made for human beeings. Bjoern
Oct 01 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BLS wrote:
 Bill Baxter schrieb:
 BLS wrote:
 div0 schrieb:
 div0 wrote:
 BLS wrote:
 div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM 
 wParam, LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this 
 will not work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal 
 construct in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the 
 garbage collectors control or pin the objects. (Don't know how 
 you do this, depends on whether you are using phobos or tango)

Tango. What means "pin the object", please explain. Bjoern

Marks the object as not movable. It looks like getAttr/setAttr is what you want, but I've not used it myself so don't blame me if your program crashes. ;) http://www.dsource.org/projects/tango/browser/trunk/lib/common tango/core/Memory.d
 You should probably look at how dfl interfaces with the Win32 
 API, http://www.dprogramming.com/dfl.ph as that library has 
 solved these issues and you should be able to work out how it's 
 doing all the necessary casting/pinning.



And to actually answer your original question: class CWin { int m_a; this() { } } extern(Windows){ typedef void* HWND; int GetWindowLongA(HWND wnd, int indx); int GetWindowLongW(HWND wnd, int indx); } void main() { // do the call (assume mbcs not unicode) int r = GetWindowLongA(cast(HWND)0, 0); // do the call & cast to CWin object pointer CWin *pWin = cast(CWin*)GetWindowLongA(cast(HWND)0, 0); Stdout( r ); } Replace the 0's with the appropriate values, ie the window handle and GWL_USERDATA (which is -21) compile with: dmd main.d user32.lib

We, means Bill B., Regan H., Jarret B. and me have discussed the C++ casting to D custing stuff a few days ago. Unfortunately our results regarding translating reinterpret_cast<CWin*> are different. Maybe we are wrong :( ... Please have a look at : http://www.prowiki.org/wiki4d/wiki.cgi?PortingFromCxx

I don't think there's anything wrong with cast(T)(cast void*) as a replacement for C's reinterpret_cast<T> -- ignoring any larger context. The issue that div0 is talking about is more global. If you're not storing your class pointers as class pointers anywhere then the garbage collector might not realize there are still live references and collect the thing prematurely.

Well, http://www.digitalmars.com/d/memory.html offers some ideas I don't understand. the docs are , in this case, too nitty gritty. qze!lra"lmirmglerhmohmj Beeing really nagged and not far away from deleting all D related stuff.

This page would seem to be more relevant: http://www.digitalmars.com/d/garbage.html (though watch out -- that page incorrectly implies that D uses a generational copying collector, which it doesn't). I don't know if you really have a GC problem or not here. Div0 is at least wrong about one thing -- the D GC will not try to move your pointer. D doesn't use that kind of GC. D's GC never moves pointers. It may delete them if it doesn't think they're in use, but it won't move them around. Basically the issue there is just that the GC only considers pointer types. So if you do something like this: size_t x = cast(size_t) new MyObject; It doesn't matter that x holds the address to MyObject. Since it holds that address in a non-pointer type, D doesn't consider it as a potential reference to memory. And if it doesn't consider 'x', then there is nothing else that points to that MyObject instance, so the GC will collect it. But BLS, taking a step back, I have to say, if you don't understand how the original code works then your chances of successfully porting it aren't good. In general, there will be parts you just have to look and and say -- "ok this won't work in D, this part I will rewrite". You have to understand the original code well enough to be able to detect those situations, and to rewrite them as needed. I've given up trying to port different STL containers a couple of times now, and the problem always comes down to not understanding the original code well enough to rewrite some part of it. And STL code is so hairy that I start thinking it would be faster to go to the library, check out a copy of Knuth's Art of Programming, read it, and implement something from scratch.
 Of course! your comments are welcome.
 Bjoern
 Beside it is this part :
 pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT ))lParam)->CtlID

 which makes me banging my head on the keyboard ;)

looks like just pWnd.GetDlgItem( (cast(LPDRAWITEMTRUCT)lParam).CtlID ) what's the confusion? --bb

For sure, C++ is not made for human beeings.

The C++ snippet does have an extra set of parentheses around the LPDRAWITEMSTRUCT, so I guess that could be confusing. And it helps to know that in Microsoft-land "LPFOO" is just crazy talk for "FOO*". --bb
Oct 01 2007
parent BLS <nanali nospam-wanadoo.fr> writes:
Bill Baxter schrieb:
 BLS wrote:
 Bill Baxter schrieb:
 BLS wrote:
 div0 schrieb:
 div0 wrote:
 BLS wrote:
 div0 schrieb:
 BLS wrote:
 Hi and sorry about picking on your nerves again  :(
 // C++
 class CWin
 {
 //
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM 
 wParam, LPARAM lParam)
 {
   CWin* pWnd=NULL;  // init pWnd
 }

 // later ...
 CWin* pChild=reinterpret_cast<CWin*>((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );


 }

 //our D class
 class CWin
 {
 static LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 {
   CWin pWnd=null;  // init pWnd as    ---reference !
 }
 /* instead of :
 CWin* pChild=reinterpret_cast<CWin*>
 we use
 CWin pChild = cast(CWin) cast(void*)

 But I am not sure how to translate :
 ((HWND)
 ::GetWindowLong(pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT 
 )lParam)->CtlID) ),GWL_USERDATA) );
 */

 // Later we have
 if (HIWORD(pWnd))

 /*Since we are working with a ref. instead of a pointer this 
 will not work.
 I guess I can use :
 */

 if (HIWORD(cast(void*)pWnd))
 // can you confirm
 }

 GetWindowLong() is a Windows Api func., sure you know it.
 So what the correct translation ?
 Bjoern
 Beside, I still wonder : Having a class A, Is A* pA a legal 
 construct in D.
 What is pA from a technical view; a pointer to a reference ?

Even if you get this to compile it won't work. (well it will till one day until it just crashes mysteriously) At some point the garbage collector might decide move your Cwin object, invalidating the pointer you are trying to store with SetWindowLong/GetWindowLong.

Thanks div0, I am allready afraid that this is the case...
 You'll have to either allocation your cwin objects outside the 
 garbage collectors control or pin the objects. (Don't know how 
 you do this, depends on whether you are using phobos or tango)

Tango. What means "pin the object", please explain. Bjoern

Marks the object as not movable. It looks like getAttr/setAttr is what you want, but I've not used it myself so don't blame me if your program crashes. ;) http://www.dsource.org/projects/tango/browser/trunk/lib/common tango/core/Memory.d
 You should probably look at how dfl interfaces with the Win32 
 API, http://www.dprogramming.com/dfl.ph as that library has 
 solved these issues and you should be able to work out how it's 
 doing all the necessary casting/pinning.



And to actually answer your original question: class CWin { int m_a; this() { } } extern(Windows){ typedef void* HWND; int GetWindowLongA(HWND wnd, int indx); int GetWindowLongW(HWND wnd, int indx); } void main() { // do the call (assume mbcs not unicode) int r = GetWindowLongA(cast(HWND)0, 0); // do the call & cast to CWin object pointer CWin *pWin = cast(CWin*)GetWindowLongA(cast(HWND)0, 0); Stdout( r ); } Replace the 0's with the appropriate values, ie the window handle and GWL_USERDATA (which is -21) compile with: dmd main.d user32.lib

We, means Bill B., Regan H., Jarret B. and me have discussed the C++ casting to D custing stuff a few days ago. Unfortunately our results regarding translating reinterpret_cast<CWin*> are different. Maybe we are wrong :( ... Please have a look at : http://www.prowiki.org/wiki4d/wiki.cgi?PortingFromCxx

I don't think there's anything wrong with cast(T)(cast void*) as a replacement for C's reinterpret_cast<T> -- ignoring any larger context. The issue that div0 is talking about is more global. If you're not storing your class pointers as class pointers anywhere then the garbage collector might not realize there are still live references and collect the thing prematurely.

Well, http://www.digitalmars.com/d/memory.html offers some ideas I don't understand. the docs are , in this case, too nitty gritty. qze!lra"lmirmglerhmohmj Beeing really nagged and not far away from deleting all D related stuff.

This page would seem to be more relevant: http://www.digitalmars.com/d/garbage.html (though watch out -- that page incorrectly implies that D uses a generational copying collector, which it doesn't). I don't know if you really have a GC problem or not here. Div0 is at least wrong about one thing -- the D GC will not try to move your pointer. D doesn't use that kind of GC. D's GC never moves pointers. It may delete them if it doesn't think they're in use, but it won't move them around. Basically the issue there is just that the GC only considers pointer types. So if you do something like this: size_t x = cast(size_t) new MyObject; It doesn't matter that x holds the address to MyObject. Since it holds that address in a non-pointer type, D doesn't consider it as a potential reference to memory. And if it doesn't consider 'x', then there is nothing else that points to that MyObject instance, so the GC will collect it.

 But BLS, taking a step back, I have to say, if you don't understand how 
 the original code works then your chances of successfully porting it 
 aren't good.  In general, there will be parts you just have to look and 
 and say -- "ok this won't work in D, this part I will rewrite".  You 
 have to understand the original code well enough to be able to detect 
 those situations, and to rewrite them as needed.

I guess you are right and I appreciate your still encouraging words. My very optimistic goal was to translate the whole library within 3 weeks or so, because the original code doesn't look very complicated. But I have to realize that a 1:1 translation will not make much sense. (at least for some parts of the lib) And indeed, The leaning by translating approach failes.
 
 I've given up trying to port different STL containers a couple of times 
 now, and the problem always comes down to not understanding the original 
 code well enough to rewrite some part of it.  And STL code is so hairy 
 that I start thinking it would be faster to go to the library, check out 
 a copy of Knuth's Art of Programming, read it, and implement something 
 from scratch.
 
 Of course! your comments are welcome.
 Bjoern
 Beside it is this part :
 pWnd->GetDlgItem( ((( LPDRAWITEMSTRUCT ))lParam)->CtlID

 which makes me banging my head on the keyboard ;)

looks like just pWnd.GetDlgItem( (cast(LPDRAWITEMTRUCT)lParam).CtlID ) what's the confusion? --bb

For sure, C++ is not made for human beeings.

The C++ snippet does have an extra set of parentheses around the LPDRAWITEMSTRUCT, so I guess that could be confusing. And it helps to know that in Microsoft-land "LPFOO" is just crazy talk for "FOO*". --bb

Oct 02 2007