C++ cast to D cast again :)

BLS nanali at nospam-wanadoo.fr
Mon Oct 1 07:46:12 PDT 2007


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.
> 
... 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.

>> 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
((still Bad) case) of progammer's confusion. :(
For sure, C++ is not made for human beeings.

Bjoern


More information about the Digitalmars-d-learn mailing list