digitalmars.D.learn - C++ cast to D cast again :)
- BLS (44/44) Sep 30 2007 Hi and sorry about picking on your nerves again :(
- downs (3/5) Sep 30 2007 Yes, and yes. :)
- BLS (6/12) Sep 30 2007 Thanks,
- div0 (13/66) Sep 30 2007 Even if you get this to compile it won't work.
- BLS (6/78) Sep 30 2007 Thanks div0,
- div0 (5/89) Sep 30 2007 Marks the object as not movable.
- div0 (25/119) Sep 30 2007 And to actually answer your original question:
- BLS (11/141) Oct 01 2007 We, means Bill B., Regan H., Jarret B. and me have discussed the C++
- Bill Baxter (11/153) Oct 01 2007 I don't think there's anything wrong with cast(T)(cast void*) as a
- BLS (10/168) Oct 01 2007 ... Storing your class pointers as class pointers anywhere ...
- Bill Baxter (33/202) Oct 01 2007 This page would seem to be more relevant:
- BLS (8/219) Oct 02 2007 I guess you are right and I appreciate your still encouraging words.
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
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
downs schrieb:BLS wrote:Thanks, weird.. How to deref. this stuff. ------ still hope someone is able to solve my C++ cast to D cast problem. BjoernBeside, 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
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
div0 schrieb:BLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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
BLS wrote:div0 schrieb: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.dBLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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
div0 wrote:BLS wrote: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.libdiv0 schrieb: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.dBLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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
div0 schrieb:div0 wrote: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 ;)BLS wrote: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.libdiv0 schrieb: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.dBLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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.
Oct 01 2007
BLS wrote:div0 schrieb: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.div0 wrote: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?PortingFromCxxBLS wrote: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.libdiv0 schrieb: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.dBLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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.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
Bill Baxter schrieb:BLS wrote:... Storing your class pointers as class pointers anywhere ... 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.div0 schrieb: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.div0 wrote: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?PortingFromCxxBLS wrote: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.libdiv0 schrieb: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.dBLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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.((still Bad) case) of progammer's confusion. :( For sure, C++ is not made for human beeings. BjoernOf 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
BLS wrote:Bill Baxter schrieb: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.BLS wrote:... Storing your class pointers as class pointers anywhere ... 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.div0 schrieb: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.div0 wrote: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?PortingFromCxxBLS wrote: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.libdiv0 schrieb: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.dBLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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.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((still Bad) case) of progammer's confusion. :( For sure, C++ is not made for human beeings.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
Bill Baxter schrieb:BLS wrote:Bill Baxter schrieb: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.BLS wrote:... Storing your class pointers as class pointers anywhere ... 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.div0 schrieb: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.div0 wrote: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?PortingFromCxxBLS wrote: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.libdiv0 schrieb: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.dBLS wrote:Thanks div0, I am allready afraid that this is the case...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)Tango. What means "pin the object", please explain. BjoernYou 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.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.Thanks BillThe 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((still Bad) case) of progammer's confusion. :( For sure, C++ is not made for human beeings.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 02 2007