Well, I answered my own question, so I thought I'd share the asnwer with you.
First, don't use a char[] array. In .NET the char's are double byte.
Use a byte[] array.
Secondly, you have to use marshal code to get the job done, but it is actually pretty easy if you are dealing with base data types within the struct. (i.e. not strings -- although, from the examples that I've seen that wouldn't be that difficult)
I also changed my struct to a class that looked something like the following:
Code:
public class mySpec {
short field1;
short field2;
byte field3;
int reserved4;
byte field5;
short field6;
}
After creating this class structure definition, I added a method called
ToByteArray which is what uses the marshal code.
Code:
public byte[] ToByteArray()
{
IntPtr ptrDef = Marshal.AllocCoTaskMem(16);
Marshal.WriteInt16(ptrDef,0,this.field1);
Marshal.WriteInt16(ptrDef,2,this.field2);
Marshal.WriteInt16(ptrDef,4,this.field3;
Marshal.WriteInt32(ptrDef,5,this.Reserved4);
Marshal.WriteByte(ptrDef,9,this.field5);
Marshal.WriteByte(ptrDef,11,this.field6);
byte[] myChars = new byte[12];
Marshal.Copy(ptrDef,myChars,0,12);
Marshal.FreeCoTaskMem(ptrDef);
return myChars;
}
The first line of the method uses the Marshal method
AllocCoTaskMem to create an unmanaged memory location to stuff the structure into.
The next 6 lines uses an overloaded verion of
WriteInt16,
WriteByte, and
WriteInt32 to write the specified field to a specified offset from the beginning of the ptrDef pointer.
Next I allocate 12 bytes in an array and use the
Marshal.Copy method to copy the bytes from the ptrDef unmanaged memory location to a managed memory byte[] array and return that array. Now my structure is nicely packaged into a byte array.
Why use this?
Glad you asked. I am working on a object to wrap the Btrieve database API. To define a file, you need to pass the Btrieve BTRCALL function a byte array with a File Descriptor, followed by the Key Descriptors for the file.
Not having an example for the above, took some wrestling to get it figured out and working. As an alternative, you could use the StrutureToPtr to copy the whole structure to the unmanaged memory, but then you have to add attributes to the Class definition to define the order for the fields to keep .NET from rearranging them.
Well, I hope this helps someone.
Scott