On 2/27/2011 10:39 PM, Steven Schveighoffer wrote:
On Sat, 26 Feb 2011 19:46:18 -0500, Tyro[a.c.edwards] <nos...@home.com>
wrote:

On 2/27/2011 8:52 AM, Simen kjaeraas wrote:
Tyro[a.c.edwards] <nos...@home.com> wrote:

I'm trying to convert some c++ code that defines

T func(par...)
{
Controller * pCtrl = WinGetLong<Controller *> (hwnd);
.
.
.
switch(msg)
{
case FirstMatch:
pCtrl = new Controller (hwnd, reinterpret_cast<CREATESTRUCT *>
(lParam));
break;
}
}

I'm not sure why I need a pointer to the class, just trying to figure
it out.

Ah. You would not need a pointer to the class in D. Instead, your
function
would look something like this:

T funct(par...)
{
auto pCtrl = WinGetLong!Controller(hwnd);
...
switch(msg)
{
case FirstMatch:
pCtrl = new Controller(hWnd, cast(CREATESTRUCT*)lParam);
break;
}
}

C++ classes are in some ways more akin to D structs, in that:

class A {};

void foo(){
A bar;
}

bar would be allocated on the stack in C++, while in D bar would be a
pointer to a class instance on the heap. (well, it would be null, but
when you set it to something, that something would reside on the heap)


Ok, that's essentially what I have, except that I used Controller
pCtrl vice auto. WinGetLong however, is a template that calls
GetWindowLongPtrA() and casts it's result (in this case) to
Controller. GetWindowLongPtrA() returns LONG_PTR (aka int) and
therefore fails miserably on the cast attempt. On the reverse, there
is a WinSetLong that attempts to cast Controller to int for use with
SetWindowLongPtrA(). Neither of these functions complain when I use
Controller* but I end up with the problem of trying to initialize a
pointer with a reference to Controller.

You almost certainly do not want a pointer to a class reference. A class
typically resides on the heap, but the reference typically does not.
Therefore, by using a pointer to a class reference, you run very high
risk of escaping stack data, leading to memory corruption.

Looking at the documentation for GetWindowLongPtr, it appears to get
data associated with a window. Likely, this information is the a pointer
to the Controller class.

I would recommend doing this:

T WinGetLong(T)(HWND hwnd)
{
return cast(T)cast(void*)GetWindowLongPtrA(hwnd, ...);
}

and

void WinSetLong(T)(HWND hwnd, T t)
{
SetWindowLongPtrA(hwnd, ..., cast(LONG_PTR)cast(void*)t);
}

where the ... is the index copied from the C++ code (guessing it's
GWLP_USERDATA?).

btw, reinterpret_cast<T>(x) is equivalent to (T)(void *)x;

-Steve

Thank you all (Steve, Bekenn, and Simen) for your assistance on this.

Reply via email to