C++ cast to D cast again :)

Bill Baxter dnewsgroup at billbaxter.com
Mon Oct 1 04:49:01 PDT 2007


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


More information about the Digitalmars-d-learn mailing list