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