Tom
It was all going so well, until
<Exception>
An unhandled exception of type 'System.TypeLoadException' occurred in
Unknown Module.
Additional information: Could not load type union from assembly MyAssembly,
Version=1.0.1670.28085, Culture=neutral, PublicKeyToken=null because it
contains an object field at offset 4 that is incorrectly aligned or
overlapped by a non-object field.
</Exception>
I have defined the structures as you suggest, but get the exception above.
It occurs because of the following statement
Dim de As DEBUG_EVENT
Here are the complete definitions
<Definitions>
<StructLayout(LayoutKind.Sequential)> Public Structure EXCEPTION_RECORD
Public ExceptionCode As ExceptionCodes
Public ExceptionFlags As ExceptionFlags
Public ExceptionRecord As IntPtr
Public ExceptionAddress As IntPtr
Public NumberParameters As Integer
Public ExceptionInformation() As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
EXCEPTION_DEBUG_INFO
Public ExceptionRecord As EXCEPTION_RECORD
Public dwFirstChance As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
CREATE_THREAD_DEBUG_INFO
Public hThread As IntPtr
Public lpThreadLocalBase As IntPtr
Public lpStartAddress As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
CREATE_PROCESS_DEBUG_INFO
Public hfile As IntPtr
Public hProcess As IntPtr
Public hThread As IntPtr
Public lpBaseOfImage As IntPtr
Public dwDebugInfoFileOffset As Integer
Public nDebugInfoSize As Integer
Public lpThreadLocalBase As IntPtr
Public lpStartAddress As IntPtr
Public lpImageName As IntPtr
Public fUnicode As Int16
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
EXIT_THREAD_DEBUG_INFO
Public dwExitCode As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
EXIT_PROCESS_DEBUG_INFO
Public dwExitCode As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
LOAD_DLL_DEBUG_INFO
Public hFile As IntPtr
Public lpBaseOfDll As IntPtr
Public dwDebugInfoFileOffset As Integer
Public nDebugInfoSize As Integer
Public lpImageName As IntPtr
Public fUnicode As Int16
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
UNLOAD_DLL_DEBUG_INFO
Public lpBaseOfDll As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure
OUTPUT_DEBUG_STRING_INFO
Public lpDebugStringData As IntPtr
Public fUnicode As Int16
Public nDebugStringLength As Int16
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure RIP_INFO
Dim dwError As Integer
Dim dwType As Integer
End Structure
<StructLayout(LayoutKind.Explicit)> Public Structure union
<FieldOffset(0)> Public Exception As EXCEPTION_DEBUG_INFO
<FieldOffset(0)> Public CreateThread As CREATE_THREAD_DEBUG_INFO
<FieldOffset(0)> Public CreateProcessInfo As
CREATE_PROCESS_DEBUG_INFO
<FieldOffset(0)> Public ExitThread As EXIT_THREAD_DEBUG_INFO
<FieldOffset(0)> Public ExitProcess As EXIT_PROCESS_DEBUG_INFO
<FieldOffset(0)> Public LoadDll As LOAD_DLL_DEBUG_INFO
<FieldOffset(0)> Public UnloadDll As UNLOAD_DLL_DEBUG_INFO
<FieldOffset(0)> Public DebugString As OUTPUT_DEBUG_STRING_INFO
<FieldOffset(0)> Public RipInfo As RIP_INFO
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure DEBUG_EVENT
Public dwDebugEventCode As Integer
Public dwProcessId As IntPtr
Public dwThreadId As IntPtr
Public u As union
End Structure
</Definitions>
Can you spot the mistake?
Charles
"Tom Shelton" <to*@YOUKNOWTHEDRILLmtogden.com> wrote in message
news:xq******************************@40tude.net.. .
On Wed, 28 Jul 2004 16:19:17 +0100, Charles Law wrote:
Can anyone suggest how I would marshal a variable length structure back
from an API call. Specifically, I am looking at the WaitForDebugEvent
function, which returns a DEBUG_EVENT structure.
However, the DEBUG_EVENT structure is defined as a union, and the size
and contents vary depending on the event code contained in the header.
typedef struct _DEBUG_EVENT {
DWORD dwDebugEventCode;
DWORD dwProcessId;
DWORD dwThreadId;
union {
EXCEPTION_DEBUG_INFO Exception;
CREATE_THREAD_DEBUG_INFO CreateThread;
CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
EXIT_THREAD_DEBUG_INFO ExitThread;
EXIT_PROCESS_DEBUG_INFO ExitProcess;
LOAD_DLL_DEBUG_INFO LoadDll;
UNLOAD_DLL_DEBUG_INFO UnloadDll;
OUTPUT_DEBUG_STRING_INFO DebugString;
RIP_INFO RipInfo;
} u;
} DEBUG_EVENT, *LPDEBUG_EVENT;
I can translate this to VB.NET, but the marshalling eludes me.
TIA
Charles
Charles, you'll want to do something like this:
<structlayout(layoutkind.sequential)> _
public structure exception_debug_info
....
end structure
<structlayout(layoutkind.sequential)> _
public structure create_thread_debug_info
...
end structure
....
<structlayout(layoutkind.explicit)> _
public structure union
<fieldoffset(0)> _
public Exception as exception_debug_info
<fieldoffset(0)> _
public CreateThread as create_thread_debug_info
...
end structure
<sturctlayout(layoutkind.sequential)>
public structure debug_event
public dwDebugEventCode As Integer
public dwProcessId As IntPtr
public dwThreadId As IntPtr
public u As union
end structure
then you can use something like this to access the values:
if debugEvent.dwDebugEventCode = EXCEPTION_DEBUG_EVENT Then
debugEvent.u.Exception.blah_blah_blah
end if
Make sense?
--
Tom Shelton [MVP]