> Here is how I would fix it.
>
[quoted text clipped - 12 lines]
> the byte* to char*
> ...

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
> <snip>
>
[quoted text clipped - 5 lines]
> of the way - all it needs to do is pass in a pointer, without doing any
> extra copying. Is there any way of doing this?
The callee (kernel32 function) stores the value of a TimeZoneInformation
structure into the location pointed to by the caller (here to "info" on the
callers stack) .
The marshaller stays out of the picture as long as the structure contains
only blittable types, however, a *char* is non-blittable , so the marshaller
must convert the source (Unicode or MBCS) buffer to the dest *char* buffer.
This conversion occurs after the actual store of the value type, this
requires some *extra copying* of the fixed char array's (which is what you
meant I guess).
This is the point where the marshaller goes wrong (a bug!), he treats the
return buffer as a MBCS, irrespective the CharSet attribute, that means that
the conversion stops after the first character in case of a Unicode buffer.
One way to prevent this *extra copying* is to make the structure blittable
(as I illustrated).
>> Here is how I would fix it.
>>
[quoted text clipped - 18 lines]
>
> Out of interest, have you used the new-to-C#2 fixed buffers?
We maintain company wide "Programming Guidelines" that define the usage
context of API's an features of a product (MS and others). For C# and the
FCL, we have three categories of API guidelines (the red, orange and green
books), the green book lists all API's that can safely be used in production
code, the orange book lists (annotated) all API's that need special care,
they may be used for prototyping and in "trusted" libraries, while the red
book lists the "prohibited" API's and features.
"unsafe" constructs and "fixed" are in the orange book for V2 they need some
care as they may cause unexpected behavior when used (as illustrated).
>Have you
> found them handy? I can't say I've ever used them before, as I very
> rarely touch unsafe code in the first place. Have you encountered them
> outside interop?
Honestly, I don't write that much code these days, but IMO they have not
much value outside interop.
Willy.
Jon Skeet [C# MVP] - 12 Jul 2007 19:14 GMT
> >> I have encountered the same issue some time ago, I guess the marshaler
> >> ignores the CharSet attribute for fixed char buffers and considers the
[quoted text clipped - 13 lines]
> requires some *extra copying* of the fixed char array's (which is what you
> meant I guess).
Right - in this case I want to basically tell the marshaller that it
really *is* blittable, just get on with it.
> This is the point where the marshaller goes wrong (a bug!), he treats the
> return buffer as a MBCS, irrespective the CharSet attribute, that means that
> the conversion stops after the first character in case of a Unicode buffer.
> One way to prevent this *extra copying* is to make the structure blittable
> (as I illustrated).
Right - and there's no way of doing that while still using a char
buffer?
> > Yup, that appears to fix it. (I thought I'd tried something like that
> > before, but apparently not.)
[quoted text clipped - 10 lines]
> "unsafe" constructs and "fixed" are in the orange book for V2 they need some
> care as they may cause unexpected behavior when used (as illustrated).
Indeed!
> >Have you
> > found them handy? I can't say I've ever used them before, as I very
[quoted text clipped - 3 lines]
> Honestly, I don't write that much code these days, but IMO they have not
> much value outside interop.
Okay - thanks for that.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Willy Denoyette [MVP] - 12 Jul 2007 20:10 GMT
>> >> I have encountered the same issue some time ago, I guess the marshaler
>> >> ignores the CharSet attribute for fixed char buffers and considers the
[quoted text clipped - 32 lines]
> Right - and there's no way of doing that while still using a char
> buffer?
It should have done it in your case (a Unicode encode struct), but it can't
do it when the native structure holds Ansi character buffers. The Ansi
buffer need to be *marshaled* to a fixed char buffer (Unicode only) .
Consider this sample:
a "native" Ansi encoded structure:
stuct MyNativeStruct {
fixed char buff[16];
int val;
}
and it's C# counterpart:
stuct MyManagedStruct {
fixed char buff[16];
int val;
}
here MyNativeStruct.buff is 16 bytes, while the MyManagedStruct.buff is 32
bytes. You can't treat the structure as blittable and just pass the
structure as is, both the char encoding and the lay-out don't match, so you
need to marshal.
Willy.
Jon Skeet [C# MVP] - 12 Jul 2007 21:33 GMT
> > Right - and there's no way of doing that while still using a char
> > buffer?
>
> It should have done it in your case (a Unicode encode struct), but it can't
> do it when the native structure holds Ansi character buffers. The Ansi
> buffer need to be *marshaled* to a fixed char buffer (Unicode only) .
Yup - that makes perfect sense. I was only considering the cases where
the structure really was going to be filled with Unicode characters in
the first place.
Hmm. I'm still looking for a really good example of using this...

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too