Re: Casting Byte Buffer returned from CeReadRecordPropsEx to CEPROPVAL in C#



You have structs that are indeed set with an unaligned packing? If that's
the case, use explicit layout and put the members where you need them. I've
never tried this, and have no idea what the marhsaler will do though.

Your safest bet would be to just pass in a giant byte array the size of the
struct and then use Marshal/BitConverter/Buffer to move the data from that
array to meaningful members of a class.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


<GBNick72@xxxxxxxxx> wrote in message
news:3ad752d0-2b1e-4f35-baa2-55d2aa0204f2@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
On Mar 20, 9:48 am, "GBNic...@xxxxxxxxx" <GBNic...@xxxxxxxxx> wrote:
Hi,

Thanks for the replies I will make the requested changes and see if it
helps.

GBNick72.

On Mar 20, 1:23 am, "Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com>
wrote:



Without looking at the actual C headers for these I already see a few
problems. This is just a first pass so it's by no means an exhaustive
list.

1) You have this:

internal struct CEVALUNION
{
short iVal; // Int16
UInt16 uiVal; // UInt16
int lVal; // Int32
UInt16 ulVal; // UInt32
//[MarshalAs(UnmanagedType.R8)]
DateTime filetime; // DateTime

Your 4th value (ulVal) you have commented as a UInt32 but defined as a
UInt32. As defined (as 16 bits) it leaves filetime WORD aligned instead
of
DWORD aligned, so the compiler is going to stuff another short in there.

2) I'm not sure how a managed DateTime marshals. You certainly want to
check that and see if it maches your target structure (FILETIME?
SYSTEMTIME?).

3) Never marshal a BOOL as a managed bool without a MarshalAs decorator.
Native is 32-bit, managed is 8.

4) WTF is this?
IntPtr ptrBuf = new IntPtr(0);

Use IntPtr.Zero, or better yet, leave it as the zero it gets initialized
to
to begin with.

5) What's up with this?
IntPtr tmp = new IntPtr(hCatDB);

hCatDB (presumably returned from CeOpenDatabase) isn't already an
IntPtr?

6) Don't pass '1' as the second parameter to CeReadRecordProps. Use a
constant or named variable so it has some meaning. WTF does "1' mean? I
have to go to the docs to find out.

7) Don't mix int, short with Int32, Int16, etc. It's hard to read.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com

<GBNic...@xxxxxxxxx> wrote in message

news:a648d016-107b-41fb-897d-94b1eb8b1fda@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi Peter,

Thanks again for the reply. I did try Marshal.PtrToStructure first
but it did not work just threw exceptions. So I thought I'll try it
as a buffer to see if that makes any difference. I'm thinking it's
probably my structs again. I have been trying different settings but
no luck here is what I have currently :-

[StructLayout(LayoutKind.Auto)]//, CharSet = CharSet.Unicode)]
internal struct CEBLOB
{
int isize;
//[MarshalAs(UnmanagedType.ByValArray)]
IntPtr pbuf;
}

//unsafe public class CEVALUNION
[StructLayout(LayoutKind.Auto)]//, CharSet=CharSet.Unicode)]
internal struct CEVALUNION
{
short iVal; // Int16
UInt16 uiVal; // UInt16
int lVal; // Int32
UInt16 ulVal; // UInt32
//[MarshalAs(UnmanagedType.R8)]
DateTime filetime; // DateTime
//[MarshalAs(UnmanagedType.LPWStr)]
string lpwstr; // Unicode string pointer
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
CEBLOB blob; // BLOB
Boolean boolVal; // Boolean (Int32)
Double dblVal; // Double
}

//unsafe public class CEPROPVAL
[StructLayout(LayoutKind.Auto)]//, CharSet=CharSet.Unicode)]
internal struct CEPROPVAL
{
int propid; // Property ID
Int16 wLenData; // Private
Int16 wFlags; // Field flags
CEVALUNION val; // Property value
}

I have tried marshaling in different ways but it seems to make no
difference. I have also tried with the layoutkind set to sequential.
I thought auto sounds safest.

Int16 nmProps = 0;
int[] PropRetrieve = null;// new int[1];
//PropRetrieve[0] = (int)((((System.UInt32)(31)) << 16) |
((System.UInt32)(0x0020)));
int dwBuff = 0;//2048;
//IntPtr ptrBuf = Marshal.AllocHGlobal(2048);
IntPtr ptrBuf = new IntPtr(0);
IntPtr tmp = new IntPtr(hCatDB);
Int32 lRec = 0;

lRec = CeReadRecordPropsEx(tmp,1,ref nmProps,PropRetrieve,ref
ptrBuf,ref dwBuff,System.IntPtr.Zero);

I was expecting to see ptrBuf == null after the call and dwBuff set to
the required size. Though after the call ptrBuf is set and the dwBuff
is also set along with nmProps. It's been a while since I have gone
down to the raw DB's but I think unless you call with the correct size
buffer you have to alloc the memory and then make a second call?,
unless you use the heap. I tried with a buffer set to 2048 just
incase the data returned in ptrBuf was invalid it did not make any
difference.

CEPROPVAL [] data;
data = (CEPROPVAL[])Marshal.PtrToStructure(ptrBuf, typeof(CEPROPVAL));

I have also tried it as typeof(CEPROPVAL[]);

It's in the conversion to the structure it throws the exception.

thanks again

GBNick72.

On Mar 18, 7:23 pm, "Peter Foot" <feedb...@xxxxxxxxxxxxxxxxxxxx>
wrote:

PtrToStructure works from an IntPtr so you don't need to copy to a
byte
array. CEPROPVAL is a fixed size structure, however it contains a
union.
In
.NETCF 2.0 and above you can set the StructLayout to
LayoutKind.Explicit
and
use the FieldOffset attribute to specify the offset in bytes to each
field.
The CEBLOB is just 8 bytes - contains a length and a pointer to the
actual
data, and the string is a pointer so in either case CEPROPVAL is
always 16
bytes long.

Peter

--
Peter Foot
Microsoft Device Application Development MVP
peterfoot.net | appamundi.com | inthehand.com
APPA Mundi Ltd - software solutions for a mobile world
In The Hand Ltd - .NET Components for Mobility

<GBNic...@xxxxxxxxx> wrote in message

news:dc3f2658-9590-4201-a8f2-59ae3d6f6c11@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Hi All,

I have used Marshal.Copy(...) to convert the data returned from
CeReadRecordPropsEx (ref to an IntPtr) back to a byte array. I then
use Marshal.PtrToStructure(...) to try and convert the byte array
back
into a CEPROPVAL structure. This seems to throw an exception I think
it is because C# expects a fixed size object where the CEPROPVAL
structure is variable due to the BLOB and the String. I think this
is
one of C# 's little niggles, in C++ it's just a simple cast. I tried
using unsafe as well which did not help. I found a solution on code
project but it requires the use of a C++ dll which is not what I
really wanted, it seems like you have to rely on C++ to get around
these issues. Shame the EDB api is not part of the compact
framework. Any ideas any one?.

thanks in advance.

GBNick72.- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Just a quick question regarding the layout of the structures are the
structures in EDB layed out with a Pack = 1 or greater?. I know you
can't use Pack in the Compact Frame Work Layout Options, but I still
need to know so I can layout the fields. I have tried it as 1 and it
seems to get past the PtrToStruct without throwing any exception but
the CEPROPVAL array doesn't seem to contain data if I try and access
the elements.

thanks in advance

GBNick72.


.



Relevant Pages

  • Re: Casting Byte Buffer returned from CeReadRecordPropsEx to CEPROPVAL in C#
    ... use explicit layout and put the members where you need them. ... UInt16 uiVal; // UInt16 ... IntPtr tmp = new IntPtr; ... internal struct CEBLOB ...
    (microsoft.public.pocketpc.developer)
  • Re: Pre-offsetof() question
    ... > now-standard offsetof() macro. ... consider the typical layout of ... pre-offsetofcompiler decide to make ... > the layout of the struct vary, ...
    (comp.lang.c)
  • Re: [RFC] x86: xsave/xrstor support, ucontext_t extensions
    ... Appended patch adds the support for xsave/xrstor infrastructure for x86. ... only user-space consumer of kernel types: there are other libcs, ... struct sigcontext uc_mcontext; ... You're changing the layout of struct ucontext in two ways: ...
    (Linux-Kernel)
  • Re: Structure size directives
    ... struct foo { ... The fact that MANY compilers give the programmer ... The best way for the compiler to give the programmer a way to specifiy ... forcing a structure layout to meet some external constraint may be. ...
    (comp.lang.c)
  • Why does my PrinterSettings.GetHdevmode() returns garbage ???
    ... IntPtr pDevMode = GlobalLock; ... // I tried with 3 different printers as default printers and I still get the ... here is the definition of my DEVMODE struct. ... public int dmPelsWidth; ...
    (microsoft.public.dotnet.languages.csharp)

Loading