D - Converting struct to ubyte[] array
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
"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,Iwanted to use an inline struct definition for the *entire* Win32 dialogboxtemplate and the dialog items, which have some embedded Unicode null-terminated strings. So I put some wchar[] dynamic arrays in thestructdefinition. It turns out that a pointer/length pair is being storedinsteadof the actual Unicode chars, and that's not what Windows likes to "see"whenit 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