www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Help with array maniipulation

reply ollie <ollie home.net> writes:
I have a C Struct:

   typedef struct
   {
       enum LibRaw_image_formats type; 
       ushort      height,
                   width,
                   colors,
                   bits;
       unsigned int  data_size; 
       unsigned char data[1]; 
   }libraw_processed_image_t;

with a D version:

   struct libraw_processed_image_t
   {
       LibRaw_image_formats    type; 
       ushort                  height,
                               width,
                               colors,
                               bits;
       uint                    data_size; 
       ubyte[1]                data; 
   }

libraw_dcraw_make_mem_thumb() returns a pointer to this struct.
I need to create a char[] from the data and data_size members,
ideally without copying, to send to GdkPixbufLoader.write(char[]).

If I do this:
   libraw_processed_image_t *img;
   img = libraw_dcraw_make_mem_thumb();
   char[] buf = cast(char[]) img.data[];
   GdkPixbufLoader.write(buf); // Runtime error

buf.ptr == img.data.ptr and length of both arrays is 1.
If I try:
   buf.length = img.data_size;
buf is reallocated.

Any suggestions to make buf.ptr == img.data.ptr and
buf.length = img.data_size?

Thanks
ollie
Feb 04 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/04/2014 10:58 AM, ollie wrote:

 I have a C Struct:
[...]
         uint                    data_size;
         ubyte[1]                data;
Is that the C extension where the last array in a struct can have more elements than its size? That will be a problem in D.
     }

 libraw_dcraw_make_mem_thumb() returns a pointer to this struct.
 I need to create a char[] from the data and data_size members,
 ideally without copying, to send to GdkPixbufLoader.write(char[]).

 If I do this:
     libraw_processed_image_t *img;
     img = libraw_dcraw_make_mem_thumb();
     char[] buf = cast(char[]) img.data[];
This: char[] buf = (cast(char*)img.data.ptr)[0 .. img.data_size]; However, as I said above, data won't have room for more than 1 element. In any case, treating a C array as a D slice is achieved by the following syntax: int[] D_slice = C_array[0 .. C_array_number_of_elements]; Ali
Feb 04 2014
next sibling parent ollie <ollie home.net> writes:
On Tue, 04 Feb 2014 11:16:00 -0800, Ali Çehreli wrote:


 Is that the C extension where the last array in a struct can have more 
 elements than its size? That will be a problem in D.
yes it is.
      int[] D_slice = C_array[0 .. C_array_number_of_elements];
Thank you, that gives me what I was looking for. I thought I had tried something like that. Too many moving parts with threads and context changes to call GDK/GTK functions make things very precarious. I am still getting an access violation, but your help has moved me a step nearer a solution. Thanks, ollie
Feb 04 2014
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Ali Çehreli:

 Is that the C extension where the last array in a struct can 
 have more elements than its size? That will be a problem in D.
Since V.2.065 D supports well variable-length structs. You have to use ubyte[0] data, and then allocate a large enough memory for the whole variable-length struct. Here I have written an usage example: http://rosettacode.org/wiki/Sokoban#Faster_Version Bye, bearophile
Feb 04 2014