[Mono-list] unmanaged type limitations -- no unmanaged arrays?
David Jeske
jeske@chat.net
Sat, 12 Jul 2003 08:57:22 -0700
This time I have some PInvoke information to share, so that when
someone else runs into this issue they can see what I've done.
In my ClearSilver (www.clearsilver.net, an HTML template system) C#
wrapper, I wanted to access this C-struct:
typedef struct _neo_err
{
int error;
int err_stack;
int flags;
char desc[256];
const char *file;
const char *func;
int lineno;
/* internal use only */
struct _neo_err *next;
} NEOERR;
My philosophy of using unsafe struct pointers, and just accessing the
struct out in unmanaged memory is great, and it's exactly what I want
to do. However, handling "char dest[256]" is not straightforward.
In C# arrays are reference types. Using one makes the struct a managed
type, and I can't put the array size in. The following is conceptually
what I want to do, however, it's obviously invalid:
[StructLayout(LayoutKind.Sequential)]
unsafe struct NEOERR {
public int error;
public int err_stack;
public int flags;
public byte[256] desc; // this is invalid, can't contain size
public const byte *file;
public const byte *func;
public int lineno;
/* internal use only */
private NEOERR *next;
};
This dosn't work either:
[ MarshalAs( UnmanagedType.LPStr, SizeConst=256 )]
public string desc;
Because in this case, I don't want to marshal the data. I just want to
talk to it in place. The solution I could come up with is this:
[StructLayout(LayoutKind.Explicit)]
unsafe struct NEOERR {
[FieldOffset(0)] public int error;
[FieldOffset(4)] public int err_stack;
[FieldOffset(8)] public int flags;
// public byte[256] dest; // not representable
[FieldOffset(12)] public byte dest_first_char; // use this as an address??
[FieldOffset(268)] public byte *file; // const
[FieldOffset(272)] public byte *func; // const
[FieldOffset(276)] public int lineno;
};
UGH! First, this is obviously annoying. Second, the only way I can
figure to get access to "char dest[256]" is to use "char* dest =
&nerr->dest_first_char;" and then just use dest as a pointer to the
string. I've dug through the documentation, and I can't find any
better solution.
Obviously it would be ideal if there were a way to represent a
value-type array. I wonder how Managed C++ handles "char foo[256];" in
a struct.
Anyhow, I'm not expecting a reply to this message, as I don't think
there is any great solution to this. I just figured it might be
interesting to someone else.
--
David Jeske (N9LCA) + http://www.chat.net/~jeske/ + jeske@chat.net