digitalmars.D.learn - How can I make this work?
- Jack (8/8) Feb 27 2021 I'm using a windows callback function where the user-defined
- evilrat (7/15) Feb 27 2021 Should already work like that. Just be aware that array can be
- rikki cattermole (9/11) Feb 28 2021 size_t l = cast(size_t)arr.ptr;
- Rumbu (3/11) Feb 28 2021 LPARAM is not long on 32 bits, it's int. Use LPARAM instead of
- Rumbu (8/22) Feb 28 2021 And you are passing only the address of the first element this
- Max Haughton (6/29) Feb 28 2021 Do the windows APIs expect the length in memory rather than as a
- rikki cattermole (5/6) Feb 28 2021 This sounds like its being sent via a user field to be passed to a callb...
- Adam D. Ruppe (39/43) Feb 28 2021 The best way to do this is to put the array inside a struct and
- Jack (5/51) Mar 15 2021 This is what I ended up using. using a single pointer such as
- Vinod K Chandran (4/8) Mar 16 2021 Perfect example of teaching something. Thank you for this
- Jack (2/11) Mar 16 2021 elegant approach
I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l;
Feb 27 2021
On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote:I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l;Should already work like that. Just be aware that array can be garbage collected if no references for it are kept somewhere else between set callback and the actual call, otherwise you can get some random garbage. Also be aware that such casts 99% basically a speculation, there is no guarantee that returned data is actually an int[].
Feb 27 2021
On 28/02/2021 8:05 PM, Jack wrote:int[] arr = [1, 2, 3];size_t l = cast(size_t)arr.ptr; Okay, so far so goodint[] a = cast(int[]) cast(void*) l;Umm, you haven't specified a length? int[] a = (cast(int*)l)[0 .. 3]; If the callback is being called (in effect under the current stack frame and won't escape), I would wrap the data you need in a struct and pass that to it instead by pointer. No need for heap allocation and gives a way to pass more complex data should the need arise.
Feb 28 2021
On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote:I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l;LPARAM is not long on 32 bits, it's int. Use LPARAM instead of long.
Feb 28 2021
On Sunday, 28 February 2021 at 09:04:49 UTC, Rumbu wrote:On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote:And you are passing only the address of the first element this way, loosing the array/slice length. This should work, but keep in mind that you have no warranty that the array stays in memory and it is not garbage collected. int[] arr = [1, 2, 3]; LPARAM l = cast(LPARAM)cast(void*)&arr; int[] a = *cast(int[]*)(cast(void*)l);I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l;LPARAM is not long on 32 bits, it's int. Use LPARAM instead of long.
Feb 28 2021
On Sunday, 28 February 2021 at 09:18:56 UTC, Rumbu wrote:On Sunday, 28 February 2021 at 09:04:49 UTC, Rumbu wrote:Do the windows APIs expect the length in memory rather than as a parameter? Also Rumbu can you check your email - I may have emailed you on an old email address by accident, but it's about the blog and it will be from mh240 ...On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote:And you are passing only the address of the first element this way, loosing the array/slice length. This should work, but keep in mind that you have no warranty that the array stays in memory and it is not garbage collected. int[] arr = [1, 2, 3]; LPARAM l = cast(LPARAM)cast(void*)&arr; int[] a = *cast(int[]*)(cast(void*)l);I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l;LPARAM is not long on 32 bits, it's int. Use LPARAM instead of long.
Feb 28 2021
On 28/02/2021 11:05 PM, Max Haughton wrote:Do the windows APIs expect the length in memory rather than as a parameter?This sounds like its being sent via a user field to be passed to a callback. I.e. event loop for a window. In this sort of case you only get one parameter on the callback and it is only big enough for a pointer.
Feb 28 2021
On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote:I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case?The best way to do this is to put the array inside a struct and pass the address of the struct instead. This way both length and pointer are passed, and you have the option to add more things if you ended up needing it later, and there's fewer weird things to worry about. int[] arr = [1, 2, 3]; struct MyMessage { int[] arr; } // this far is easy enough MyMessage* messagePointer = new MyMessage(arr); // but we do need to tell the GC we intend to pass this to the outside world // failure to do this MIGHT lead to random crashes as the GC can't see it (it can't look inside the Windows message queue), assumes it is unused, and frees it out from under you. import core.memory; GC.addRoot(messagePointer); // when the GC has a root, it will consider that pointer live until further notice and not collect it nor its member variables. // so it is now cool to do this PostMessage(hwnd, MSG_WHATEVER, 0, cast(LPARAM) messagePointer); /* then on the other side */ switch(iMsg) { case MSG_WHATEVER: MyMessage* messagePointer = cast(MyMessage*) lParam; // need to tell the GC the pointer can be automatically managed normally again. failure to do this will lead to a memory leak import core.memory; GC.removeRoot(messagePointer); // now can use it foreach(item; messagePointer.arr) { // yada yada yada } } And it is the simplest thing, no missing length, no weird property casting. The GC handled with two simple add/remove calls.
Feb 28 2021
On Sunday, 28 February 2021 at 13:15:47 UTC, Adam D. Ruppe wrote:On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote:This is what I ended up using. using a single pointer such as MyMessage makes things much simpler. Thanks for the rememinder of GC.removeRoot() Everyone else in this theread, thank you guys. Always helpfulI'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case?The best way to do this is to put the array inside a struct and pass the address of the struct instead. This way both length and pointer are passed, and you have the option to add more things if you ended up needing it later, and there's fewer weird things to worry about. int[] arr = [1, 2, 3]; struct MyMessage { int[] arr; } // this far is easy enough MyMessage* messagePointer = new MyMessage(arr); // but we do need to tell the GC we intend to pass this to the outside world // failure to do this MIGHT lead to random crashes as the GC can't see it (it can't look inside the Windows message queue), assumes it is unused, and frees it out from under you. import core.memory; GC.addRoot(messagePointer); // when the GC has a root, it will consider that pointer live until further notice and not collect it nor its member variables. // so it is now cool to do this PostMessage(hwnd, MSG_WHATEVER, 0, cast(LPARAM) messagePointer); /* then on the other side */ switch(iMsg) { case MSG_WHATEVER: MyMessage* messagePointer = cast(MyMessage*) lParam; // need to tell the GC the pointer can be automatically managed normally again. failure to do this will lead to a memory leak import core.memory; GC.removeRoot(messagePointer); // now can use it foreach(item; messagePointer.arr) { // yada yada yada } } And it is the simplest thing, no missing length, no weird property casting. The GC handled with two simple add/remove calls.
Mar 15 2021
On Sunday, 28 February 2021 at 13:15:47 UTC, Adam D. Ruppe wrote:And it is the simplest thing, no missing length, no weird property casting. The GC handled with two simple add/remove calls.Perfect example of teaching something. Thank you for this knowledge. Even though, this was not my problem, Its really helpful for me to my future project. :)
Mar 16 2021
On Tuesday, 16 March 2021 at 16:02:14 UTC, Vinod K Chandran wrote:On Sunday, 28 February 2021 at 13:15:47 UTC, Adam D. Ruppe wrote:elegant approachAnd it is the simplest thing, no missing length, no weird property casting. The GC handled with two simple add/remove calls.Perfect example of teaching something. Thank you for this knowledge. Even though, this was not my problem, Its really helpful for me to my future project. :)
Mar 16 2021