Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
August 16, 2004 A little direction, if anyone is so inclined... | ||||
---|---|---|---|---|
| ||||
I'm trying to create a block of memory to pass to a Windows function (LoadMenuIndirect, in winuser.h). This chuck of memory defines the menu for the window. It contains ushorts, uints, and wchars. Unfortunatly, the different elements can vary in length, and possibly not be present at all. (I put the rundown in a previous post.) I decided to try to make with work with a dynamic array of ubytes like this: #import std.c.stdio; #int main() #{ # ubyte[] storage; # ubyte* temp; # char[] text; # int num; # # text = "&File\0"; # num = 40001; # # storage ~= cast(ubyte[])text; # printf("storage.length = %d, storage = %s", storage.length, storage); # temp = cast(ubyte*)# # storage ~= temp[0..num.sizeof]; # printf("storage.length = %d, storage = %s", storage.length, storage); # return 0; #} It compiles just fine, but I get an access violation on the (first) printf(). After a bit of reading through Phobos, I'm thinking that I need to use streams, specifically a memory stream. Could anyone point me to a primer--I've never worked with streams much besides cout. Thanks, Chris Stevenson |
August 16, 2004 Re: A little direction, if anyone is so inclined... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Stevenson | You need a "%.*s" instead of "%s" in the printf() call. Also, you might take a look at the OutBuffer module instead of Stream: it's lighter. "Chris Stevenson" <Chris_member@pathlink.com> wrote in message news:cfp04j$1bfu$1@digitaldaemon.com... > I'm trying to create a block of memory to pass to a Windows function (LoadMenuIndirect, in winuser.h). This chuck of memory defines the menu for the > window. It contains ushorts, uints, and wchars. Unfortunatly, the different > elements can vary in length, and possibly not be present at all. (I put the > rundown in a previous post.) I decided to try to make with work with a dynamic > array of ubytes like this: > > #import std.c.stdio; > #int main() > #{ > # ubyte[] storage; > # ubyte* temp; > # char[] text; > # int num; > # > # text = "&File\0"; > # num = 40001; > # > # storage ~= cast(ubyte[])text; > # printf("storage.length = %d, storage = %s", storage.length, storage); > # temp = cast(ubyte*)# > # storage ~= temp[0..num.sizeof]; > # printf("storage.length = %d, storage = %s", storage.length, storage); > # return 0; > #} > > It compiles just fine, but I get an access violation on the (first) printf(). > After a bit of reading through Phobos, I'm thinking that I need to use streams, > specifically a memory stream. Could anyone point me to a primer--I've never > worked with streams much besides cout. > > Thanks, > Chris Stevenson > > |
August 16, 2004 Re: A little direction, if anyone is so inclined... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Stevenson |
Okay, you've narrowed the problem down to the first printf:
># printf("storage.length = %d, storage = %s", storage.length, storage);
You're really close to doing this correctly, its just that D has one wrinkle when using strings and printf. Use "%.*s" instead of "%s" when printing strings in printf, or just use writef instead (with the usual "%s" formatter).
- Pragma
|
August 16, 2004 Re: A little direction, if anyone is so inclined... | ||||
---|---|---|---|---|
| ||||
Posted in reply to antiAlias | In article <cfp0kp$1bou$1@digitaldaemon.com>, antiAlias says... > >You need a "%.*s" instead of "%s" in the printf() call. Also, you might take a look at the OutBuffer module instead of Stream: it's lighter. > OutBuffer. Cool. Thanks for pointing that out! Next question: std.outiffer.toBytes() returns a dynamic array of ubytes. LoadMenuIndirect takes a pointer. (The data in the array indicates the last element, with a special flag.) Can I do this? #ubyte* buildMenu() #{ # outBuffer myBuffer; #// do stuff to fill up buffer # return myBuffer.toBytes; #} Also: Hmm... I'll need to subclass OutBuffer, to add support for wchars. (yay Windows...) Would this be all I have to do? #MyOutBuffer : OutBuffer #{ # this() {super()} # void write(wchar[] s) # { # write(cast(ubyte[])s); # } #} Thanks, --Chris |
August 16, 2004 Re: A little direction, if anyone is so inclined... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Stevenson | In article <cfp3cd$1dfr$1@digitaldaemon.com>, Chris Stevenson says... > >OutBuffer. Cool. Thanks for pointing that out! > >Can I do this? > >#ubyte* buildMenu() >#{ ># outBuffer myBuffer; >#// do stuff to fill up buffer ># return myBuffer.toBytes; >#} Almost! In D, arrays are not automatically pointers. But you can write return &myBuffer.toBytes[0]; and it should work. But remember the [0], or it won't work correctly (and probably won't compile, IIRC.) >#MyOutBuffer : OutBuffer >#{ ># this() {super()} ># void write(wchar[] s) ># { ># write(cast(ubyte[])s); ># } >#} You have to include the line alias OutBuffer.write write; Since you override write(), you also remove OutBuffer.write from scope (don't ask ;-). Also, you can drop the this() since OutBuffer.this() is called anyway. Nick |
August 16, 2004 Re: A little direction, if anyone is so inclined... | ||||
---|---|---|---|---|
| ||||
Posted in reply to pragma | In article <cfp1f0$1cen$1@digitaldaemon.com>, pragma <EricAnderton at yahoo dot com> says... > > >Okay, you've narrowed the problem down to the first printf: > >># printf("storage.length = %d, storage = %s", storage.length, storage); > >You're really close to doing this correctly, its just that D has one wrinkle when using strings and printf. Use "%.*s" instead of "%s" when printing strings in printf, or just use writef instead (with the usual "%s" formatter). > >- Pragma > > > > The reason for that wrinkle, in case you're curious, is because arrays in D are actually represented in memory like the following structure: struct array { int32 length; void* data; } and that's exactly what the %.*s parameter expects, a length followed by a pointer to the data. -Déja |
August 16, 2004 Re: A little direction, if anyone is so inclined... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick |
>>#MyOutBuffer : OutBuffer
>>#{
>># this() {super()}
>># void write(wchar[] s)
>># {
>># write(cast(ubyte[])s);
>># }
>>#}
>
>You have to include the line
>
>alias OutBuffer.write write;
>
I was compiling with the -c flag, to check my syntax, and the compiler finally accepted this without complaint. I'm just wondering, if I extended OutBuffer Correctly:
struct MenuExTemplateHeader
{
WORD wVersion;
WORD wOffset;
DWORD dwHelpId;
}
struct MenuExTemplateItem
{
align(4)
{
DWORD dwType;
DWORD dwState;
UINT uId;
}
align(2)
{
WORD bResInfo;
}
// WCHAR[] szText; //these are variable, so
// DWORD dwHelpId; //in D, these must be seperate from struct;
}
class MenuBuffer : OutBuffer
{
alias OutBuffer.write write;
alias OutBuffer.align2 align2;
alias OutBuffer.align4 align4;
void write(wchar[] s)
{
this.write(cast(ubyte[])s);
}
void write(MenuExTemplateHeader h)
{
this.write(h.wVersion);
this.write(h.wOffset);
this.write(h.dwHelpId);
}
void write(MenuExTemplateItem i)
{
this.align4();
this.write(i.dwType);
this.write(i.dwState);
this.write(i.uId);
this.align2();
this.write(i.bResInfo);
}
}
|
Copyright © 1999-2021 by the D Language Foundation