How can I map bytes to a matrix of structures?

Timon Gehr timon.gehr at gmx.ch
Fri Sep 9 13:51:38 PDT 2011


On 09/09/2011 10:25 PM, teo wrote:
> On Fri, 09 Sep 2011 17:43:04 +0200, Timon Gehr wrote:
>
>> On 09/09/2011 05:19 PM, teo wrote:
>>> Here is an example of what I am after:
>>>
>>> struct DATA
>>> {
>>>     ubyte D1;
>>>     ubyte D2;
>>>     ubyte D3;
>>>     ubyte D4;
>>> }
>>>
>>> void main()
>>> {
>>>     ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
>>>     0x01,
>>> 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ];
>>>     auto b = (cast(DATA*)a.ptr)[0 .. 4];
>>>     auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2];
>>> }
>>>
>>> I need to have a DATA[2][2]. That code compiles but gives me a
>>> segmentation fault.
>>
>> If you actually want a dynamic DATA[2][] array of length 2, this works:
>> auto b=(*(cast(DATA[2][2]*)a.ptr))[];
>>
>> Otherwise:
>>
>> A simple reinterpret cast should do:
>> auto b=*(cast(DATA[2][2]*)a.ptr);
>>
>> but note that this copies the data, because static arrays have value
>> semantics.
>>
>> If you want to have refer the new array to the same location, you can
>> use a union.
>>
>> void main(){
>>       union Myunion{
>> 	ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
> 0x01,
>> 			0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ];
>> 	DATA[2][2] b;
>>       }
>>       Myunion myunion;
>>       assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b);
>> }
>
> Thank you Timon for the good explanation.

You are welcome. As bearophile suggests, those are nicer though:

auto b=(cast(DATA[2][2]a);  // static array
auto b=(cast(DATA[2][2]a)[];// dynamic array

>
> Just one more question (I suspect the answer will be no, but let me ask):
> is it possible to directly cast to ubyte[][]?

Not directly, because you have to build some structure in memory.

an ubyte[][] is an array of dynamic arrays. Each of those dynamic arrays 
is a 2 field struct consisting of a ptr and a length field.
That data you have to construct manually.

in case you wanted to turn the ubyte[16] a array to a ubyte[][] b array, 
with b.length and b[i].length equal to 4, this would probably do the job:

ubyte[16] a=[ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x02, 
0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ];

auto b=new ubyte[][](4);// create a ubyte[][] array that can hold 4 
ubyte[] values
foreach(i,ref x;b) x=a[i*4 .. (i+1)*4]; // compute the values by slicing 
the original array









More information about the Digitalmars-d-learn mailing list