Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / January 2005

Tip: Looking for answers? Try searching our database.

Union of structs - TypeLoadException

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jason Cartwright - 21 Jan 2005 17:26 GMT
I have a union of structs that is returned from an unmanged C++ API.
Everything works fine until I add a specific type of struct
[EvEndBitInfo] as a member of the union. I know you can't mix value and
reference types in the same union, but I don't see the conflict because
I believe all members of the suspect struct are value types. Here's
what I have:

//TypeLoadException
Could not load type ...EventInfo from assembly MyAssembly,
Version=1.0.1847.20731, Culture=neutral, PublicKeyToken=null because it
contains an object field at offset 0 that is incorrectly aligned or
overlapped by a non-object field.

// Union Definition
[StructLayout(LayoutKind.Explicit)]
public struct EventInfo
{
[FieldOffset(0)] public EvErrorInfo ErrorReport;
[FieldOffset(0)] public EvPstnErrorInfo PSTNErrorReport;
[FieldOffset(0)] public EvEndBitInfo BITReport; // here's the culprit
// additional fields...
}

// EvErrorInfo struct
[StructLayout(LayoutKind.Sequential)]
public struct EvErrorInfo
{
public int ErrorCode;
public int DeviceID;
public int CID;
public int Origin;
public int LineInFile;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public char[] FileName;
public byte Length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=255)]
public char[] ErrorString;
}

// EvPstnErrorInfo struct
[StructLayout(LayoutKind.Sequential)]
public struct EvPstnErrorInfo
{
public int ErrorCode;
public int DeviceID;
public int TrunkID;
public int BChannel;
public int ConnID;
public int Origin;
public int LineInFile;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public char[] FileName;
public byte Length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=255)]
public char[] ErrorString;
public int CallHandle;
}

// EvEndBitInfo struct ::This is the culprit::
[StructLayout(LayoutKind.Sequential)]
public struct EvEndBitInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
public int[] DSPBitReturnCode;
public int FLASHBitReturnCode;
public int SDRAMBitReturnCode;
public int DPRBitReturnCode;
public int PhyTestBitReturnCode;
public int FramersBitReturnCode;
public int PCMSwitchBitReturnCode;
public int ResetSourceReportBitReturnCode;
public int NumOfAnalogChannels;
public int BoardTempBitReturnCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=24)]
public int[] FXSCRAMCheckSumBitReturnCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=24)]
public int[] VoltageCurrentBitReturnCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=24)]
public int[] FXSDuslicVersionReturnCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=24)]
public int[] FXOAnicVersionReturnCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=24)]
public int[] FXSCodecValidationBitReturnCode;
}

The only thing that distinguishes these structs is the use of int[] in
the EvEndBitInfo struct in question. Am I mistaken that int[] is a
value type?

Thanks for any insight.
Mattias Sj?gren - 21 Jan 2005 19:15 GMT
Jason,

>Am I mistaken that int[] is a value type?

Yes, all arrays are reference types.

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Jason Cartwright - 21 Jan 2005 19:25 GMT
So why do the char[] fields work and not int[]?
Mattias Sj?gren - 23 Jan 2005 10:50 GMT
>So why do the char[] fields work and not int[]?

Don't know, I wouldn't expect either to work. But TypeLoadExceptions
tend to be somewhat unpredictable.

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Jason Cartwright - 24 Jan 2005 16:08 GMT
I ended up going with an IntPtr instead of trying to recreate the union
in C#. At least that will give me the flexibility of dealing with each
expected struct individually instead of dealing with object vs.
non-object conflicts.

const int BUFSIZE = 2048;
Event boardEvent = null;

IntPtr pEI = IntPtr.Zero; // pointer to EventInfo

try
{
int channelHandle, eventInfoSize;
// alloc unmanaged memory
pEI = Marshal.AllocHGlobal((int) BUFSIZE);
EventType eventType = (EventType) acGetEvent(boardHandle, out
channelHandle, 0, 0, pEI, out eventInfoSize);

switch(eventType)
{
case EventType.acEV_NONE:
boardEvent = new Event(eventType, boardHandle, channelHandle);
break;

case EventType.acEV_ERROR:
case EventType.acEV_DEBUG:
EvErrorInfo errorInfo = (EvErrorInfo) Marshal.PtrToStructure(pEI,
typeof(EvErrorInfo));
boardEvent = new ErrorEvent(errorInfo, eventType, boardHandle,
channelHandle);
break;
}
finally
{
//deallocate unmanaged memory
if(pEI != IntPtr.Zero)
Marshal.FreeHGlobal(pEI);
}

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.