Structure in CSharp

G

Guest

Hi,

I have a structure written in C++ / VC.NET and would like to convert that
into CSharp. I am not getting any success. Can any of you please help me
out. Following is the structure in C++:

struct R_OMNI_LINK_MESSAGE
{
unsigned char MessageLength;
union {
unsigned char Data[255];
struct {
unsigned char MessageType;
union {
struct /* olmNAME_DATA (8 bit) */ {
unsigned char ItemType8;
unsigned char ItemNumber8;
unsigned char ItemName8[16];
};
struct /* olmNAME_DATA (16 bit) */ {
unsigned char ItemType16;
unsigned char ItemNumber16MSB;
unsigned char ItemNumber16LSB;
unsigned char ItemName16[16];
};
}
}
}

Thanks for all the help in advance.

Yatin Patel.
 
G

Guest

I have a DLL that provides native API call interface. I am trying to call
the functions in this dll from CSharp application and for some reason it is
failing. Following is the structure i have created in CSharp application
which is a mapping for the structure i had posted before:

[StructLayout(LayoutKind.Explicit)]
struct R_OMNI_LINK_MESSAGE
{
[FieldOffset(0)]
public byte _msgLength;
[FieldOffset(1), MarshalAs(UnmanagedType.Struct)]
public _myUnion MyStruct;
}

[StructLayout(LayoutKind.Explicit)]
public struct _myUnion
{
[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst =
255)]
public byte _messageType;
[FieldOffset(0), MarshalAs(UnmanagedType.Struct)]
public _msgType MessageType;
}

[StructLayout(LayoutKind.Explicit)]
public struct _msgType
{
[FieldOffset(0)]
public byte _messageType;
[FieldOffset(1), MarshalAs(UnmanagedType.Struct)]
public _olmSYSTEM_INFORMATION olmSYSTEM_INFORMATION;
}

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct _olmSYSTEM_INFORMATION
{
[FieldOffset(0)]
public byte ModelNumber;

[FieldOffset(1)]
public byte MajorVersion;

[FieldOffset(2)]
public byte MinorVersion;

[FieldOffset(3)]
public byte Revision;

[FieldOffset(4)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
public byte LocalPhoneNumber;
};

This for some reason is not working for LocalPhoneNumber field in the above
structure. It gives runtime error which is as below:

Cannot marshal field 'MyStruct' of type 'R_OMNI_LINK_MESSAGE': The type
definition of this field has layout information but has an invalid
managed/unmanaged type combination or is unmarshalable.

Hope this helps.

Yatin
 
M

Mattias Sjögren

[FieldOffset(4)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
public byte LocalPhoneNumber;
};

This for some reason is not working for LocalPhoneNumber field in the above
structure. It gives runtime error which is as below:

Cannot marshal field 'MyStruct' of type 'R_OMNI_LINK_MESSAGE': The type
definition of this field has layout information but has an invalid
managed/unmanaged type combination or is unmarshalable.


You can only use ByvalArray on actual array types. So the type of
LocalPhoneNumber should be byte[].


Mattias
 
P

Peter Duniho

[...]
This for some reason is not working for LocalPhoneNumber field in the
above structure. It gives runtime error which is as below:

Cannot marshal field 'MyStruct' of type 'R_OMNI_LINK_MESSAGE': The type
definition of this field has layout information but has an invalid
managed/unmanaged type combination or is unmarshalable.

Well, you're beyond me at this point. :) I haven't done enough of what
you're trying to do to consider myself very helpful on the matter.

Being ignorant's never stopped me from commenting in the past though, so
I'll point out a few of things I noticed:

One is that your _myUnion struct doesn't look to me to be the same as the
original struct you've specified. You've got as its first field a single
byte "_messageType", but the original struct has a 255-byte array named
"Data". In addition, you've instructed C# to marshal that single byte as
a 255 element array. If I were the C# compiler, I might complain about
something like that too. :)

Another thing is that the _olmSYSTEM_INFORMATION struct doesn't look like
anything in your original struct definition. This may or may not be a
problem, but I am left wondering how you got from the original struct
definition you posted to the C# declaration you've also posted.

Finally, in the same way that your declaration in "_myUnion" for the
"_messageType" field looks odd to me, so too does the declaration for
"LocalPhoneNumber" in the "_olmSYSTEM_INFORMATION" struct. It's a byte,
but you're telling C# it's an array of length 25.

I figure there's one of two possibilities: either this is actually how
you're supposed to do it, and C# has some really weird syntax that I don't
understand; or, it's not how you're supposed to do it, and you're supposed
to declare types in C# that are at least roughly the same as the unmanaged
type you're trying to get. Honestly, either one of those is possible for
all I know. But you might want to think about the possibility that it's
the latter that's causing you trouble. :)

Pete
 
G

Guest

I tried using byte[] but it gives me the following error:

Could not load type '_msgType' from assembly 'HAICntrlApp, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' because it contains an object field at
offset 1 that is incorrectly aligned or overlapped by a non-object field.

Mattias Sjögren said:
[FieldOffset(4)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
public byte LocalPhoneNumber;
};

This for some reason is not working for LocalPhoneNumber field in the above
structure. It gives runtime error which is as below:

Cannot marshal field 'MyStruct' of type 'R_OMNI_LINK_MESSAGE': The type
definition of this field has layout information but has an invalid
managed/unmanaged type combination or is unmarshalable.


You can only use ByvalArray on actual array types. So the type of
LocalPhoneNumber should be byte[].


Mattias
 
G

Guest

Peter,

I see what you are saying -- I tried almost everything. As far as your
LocalPhoneNumber point -- I think the original structure also has declared
that as Unsigned Char array of 25 characters.

I am kind of lost here.

Yatin


Peter Duniho said:
[...]
This for some reason is not working for LocalPhoneNumber field in the
above structure. It gives runtime error which is as below:

Cannot marshal field 'MyStruct' of type 'R_OMNI_LINK_MESSAGE': The type
definition of this field has layout information but has an invalid
managed/unmanaged type combination or is unmarshalable.

Well, you're beyond me at this point. :) I haven't done enough of what
you're trying to do to consider myself very helpful on the matter.

Being ignorant's never stopped me from commenting in the past though, so
I'll point out a few of things I noticed:

One is that your _myUnion struct doesn't look to me to be the same as the
original struct you've specified. You've got as its first field a single
byte "_messageType", but the original struct has a 255-byte array named
"Data". In addition, you've instructed C# to marshal that single byte as
a 255 element array. If I were the C# compiler, I might complain about
something like that too. :)

Another thing is that the _olmSYSTEM_INFORMATION struct doesn't look like
anything in your original struct definition. This may or may not be a
problem, but I am left wondering how you got from the original struct
definition you posted to the C# declaration you've also posted.

Finally, in the same way that your declaration in "_myUnion" for the
"_messageType" field looks odd to me, so too does the declaration for
"LocalPhoneNumber" in the "_olmSYSTEM_INFORMATION" struct. It's a byte,
but you're telling C# it's an array of length 25.

I figure there's one of two possibilities: either this is actually how
you're supposed to do it, and C# has some really weird syntax that I don't
understand; or, it's not how you're supposed to do it, and you're supposed
to declare types in C# that are at least roughly the same as the unmanaged
type you're trying to get. Honestly, either one of those is possible for
all I know. But you might want to think about the possibility that it's
the latter that's causing you trouble. :)

Pete
 
P

Peter Duniho

I tried using byte[] but it gives me the following error:

Could not load type '_msgType' from assembly 'HAICntrlApp,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because
it contains an object field at offset 1 that is incorrectly
aligned or overlapped by a non-object field.

Well, you're making progress. :)

IMHO, the error messages you've posted so far have been pretty
self-explanatory. I have little enough knowledge in this area as it is,
so I won't bother trying to fix anything. But I will point out that if
the compiler is complaining that you have a field that is incorrectly
aligned or overlapped by a non-object field, you should look into whether
the field is incorrectly aligned or may be illegally overlapping another
field (note that clearly you should be allowed to overlap fields somehow,
so the trick if there is an illegal overlap is to figure out how to turn
it into a legal overlap).

I wish I had better knowledge about this and could help you directly, but
hopefully you can take advantage of the error messages you're getting,
which do seem to me to state pretty specifically what's wrong.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top