www.digitalmars.com         C & C++   DMDScript  

D - Converting struct to ubyte[] array

reply "Les Baker" <lesbaker innovaREMOVETHIS.net> writes:
I am working on porting some Win32 dialog-box generation code I wrote in
C++, which uses an in-memory dialog template and DialogBoxIndirectParam() to
build a dialog box "on-the-fly". It uses the DLGTEMPLATE and DLGITEMTEMPLATE
structures, which are not terribly complex. I am trying to get them into a
ubyte[] array for use with the OutBuffer phobos class, which will eventually
go to . Unfortunately, the following doesn't seem to work well.

static DLGITEMTEMPLATE dlgButton =
{
    style : WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
    dwExtendedStyle : 0,
    x : 150,
    y : 5,
    cx : 50,
    cy : 14,
    id : IDOK
};

// a bit later in the code...
ubyte[] dlgTemplateBuf = cast(ubyte[]) (cast(ubyte *) (&dlgTemplate))[0 ..
dlgTemplate.size];
// so that I can do this
outbuf.write( dlgTemplateBuf );

Yes, it looks messy; I'm probably doing something extremely stupid, so
consider this a "D newbie question" =). I thought I could just cast to
ubyte[], but that didn't work. Has anyone else used OutBuffer with UDT's?

On a side note:

The most frustrating thing was that when I first started porting the code, I
wanted to use an inline struct definition for the *entire* Win32 dialog box
template and the dialog items, which have some embedded Unicode
null-terminated strings. So I put some wchar[] dynamic arrays in the struct
definition. It turns out that a pointer/length pair is being stored instead
of the actual Unicode chars, and that's not what Windows likes to "see" when
it is reading the dialog template. I really wish there was a property of
UDT's that would persist it as a flat array of bytes at that point in the
code. (That could be done on the user side if introspection were in D, but
even then, introspection wouldn't benefit non-class UDT's).

Les Baker
Aug 14 2003
parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Les Baker" <lesbaker innovaREMOVETHIS.net> wrote in message
news:bhgk6u$ip8$1 digitaldaemon.com...
 // a bit later in the code...
 ubyte[] dlgTemplateBuf = cast(ubyte[]) (cast(ubyte *) (&dlgTemplate))[0 ..
 dlgTemplate.size];
 // so that I can do this
 outbuf.write( dlgTemplateBuf );

 Yes, it looks messy; I'm probably doing something extremely stupid, so
 consider this a "D newbie question" =). I thought I could just cast to
 ubyte[], but that didn't work. Has anyone else used OutBuffer with UDT's?
ubyte[] (as you found out below) is a length and pointer to start of "slice" you should only need to do ubyte[] sliceme( ubyte * ptr, int start, int finish ) { ubyte[] buf = ptr[start..finish]; // is buf.addr = ptr + start; buf.len = finish - start; return buf; }
 On a side note:

 The most frustrating thing was that when I first started porting the code,
I
 wanted to use an inline struct definition for the *entire* Win32 dialog
box
 template and the dialog items, which have some embedded Unicode
 null-terminated strings. So I put some wchar[] dynamic arrays in the
struct
 definition. It turns out that a pointer/length pair is being stored
instead
 of the actual Unicode chars, and that's not what Windows likes to "see"
when
 it is reading the dialog template. I really wish there was a property of
 UDT's that would persist it as a flat array of bytes at that point in the
 code. (That could be done on the user side if introspection were in D, but
 even then, introspection wouldn't benefit non-class UDT's).
you can (ish) with templates .... template array( int size ) { struct myholder { byte[size] buf; } } instance array(8) block_of_eight; block_of_eight.myholder foo; foo.buf is byte[8] not byte[] with len of 8 however as the length is know you can pass it as a byte[] import c.stdio; ubyte[] make_raw( void * ptr, int len ) { return (cast(ubyte*)ptr)[0..len]; } template mystructs( int size ) { struct myElement { int a; } struct myholder { int length; myElement[size] buf; } ubyte[] makeStruct( int[] elements ) { if ( elements.length != size ) { throw new Exception( "invalid arg length" ); } myholder * h = new myholder(); h.length = size; for( int i = 0; i < size; i++ ) { h.buf[i].a = elements[i]; } return make_raw( h, myholder.size ); } } int main( char[][] args ) { static int[] ar = [1,2,3]; ubyte[] raw = instance mystructs(3).makeStruct( ar ); printf( "raw.length:%d\n", raw.length ); for( int i =0; i < raw.length; i++ ) { printf( "%02x ", raw[i] ); } return 0; }
Aug 14 2003