Interop marshaling

  • Thread starter Thread starter ivang
  • Start date Start date
I

ivang

Hello, All!

Please help me to marshal following win32 structure:

typedef struct _STARTUPINFOW {

DWORD cb;

LPWSTR lpReserved;

LPWSTR lpDesktop;

LPWSTR lpTitle;

DWORD dwX;

DWORD dwY;

DWORD dwXSize;

DWORD dwYSize;

DWORD dwXCountChars;

DWORD dwYCountChars;

DWORD dwFillAttribute;

DWORD dwFlags;

WORD wShowWindow;

WORD cbReserved2;

LPBYTE lpReserved2;

HANDLE hStdInput;

HANDLE hStdOutput;

HANDLE hStdError;

} STARTUPINFOW, *LPSTARTUPINFOW;

----------------



Here is what I have in C#:

[StructLayout(LayoutKind.Sequential)]

public struct STARTUPINFOW

{

ulong cb;

string lpReserved;

string lpDesktop;

string lpTitle;

ulong dwX;

ulong dwY;

ulong dwXSize;

ulong dwYSize;

ulong dwXCountChars;

ulong dwYCountChars;

ulong dwFillAttribute;

ulong dwFlags;

ushort sShowWindow;

ushort cbReserved2;

IntPtr lpReserved2;

IntPtr hStdInput;

IntPtr hStdOutput;

IntPtr hStdError;

}

Is that correct? I'm not sure about marshalling LPWSTR, LPBYTE and HANDLE
type fields.

Thanks.
 
ivang said:
Hello, All!

Please help me to marshal following win32 structure:

typedef struct _STARTUPINFOW {

DWORD cb;

LPWSTR lpReserved;

LPWSTR lpDesktop;

LPWSTR lpTitle;

DWORD dwX;

DWORD dwY;

DWORD dwXSize;

DWORD dwYSize;

DWORD dwXCountChars;

DWORD dwYCountChars;

DWORD dwFillAttribute;

DWORD dwFlags;

WORD wShowWindow;

WORD cbReserved2;

LPBYTE lpReserved2;

HANDLE hStdInput;

HANDLE hStdOutput;

HANDLE hStdError;

} STARTUPINFOW, *LPSTARTUPINFOW;

----------------



Here is what I have in C#:

[StructLayout(LayoutKind.Sequential)]

public struct STARTUPINFOW

{

ulong cb;

string lpReserved;

string lpDesktop;

string lpTitle;

ulong dwX;

ulong dwY;

ulong dwXSize;

ulong dwYSize;

ulong dwXCountChars;

ulong dwYCountChars;

ulong dwFillAttribute;

ulong dwFlags;

ushort sShowWindow;

ushort cbReserved2;

IntPtr lpReserved2;

IntPtr hStdInput;

IntPtr hStdOutput;

IntPtr hStdError;

}

Is that correct? I'm not sure about marshalling LPWSTR, LPBYTE and HANDLE
type fields.

Thanks.

Couple of things:
1. Specify the [StructLayout(LayoutKind.Sequential)] for your structure
2. Marshalling strings can be done in a few different ways, see note below
3. Marshalling pointers are usually done with IntPtr, unless you got the
type readily defined in .net (like if it's an interface pointer or
something)
4. Handle is usually done with IntPtr

Strings can be done in a variety of ways:

= String pointers provided to the interop code for *reading*:
Use the String type in .NET, optionally using the MarshalAs attribute to
specify the right marshalling, but .net automatically selects this if
you don't provide it:

[MarshalAs(UnmanagedType.LPTStr)]
public String lpReserved;

// or use [MarshalAs(UnmanagedType.LPWStr)]

= String pointers provided to the interop code for *writing* (ie.
storing characters into a string, where a pointer to the string is
specified in the struct/parameter list to the interop function):
Use a StringBuilder, and construct it with a capacity:

StringBuilder sb = new StringBuilder(260); // MAX_PATH

= Strings stored as character arrays in the struct:
Use the String type in .NET, but provide a MarshalAs attribute:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
public String Pathname;

following the above pointers, here's how I would define that struct in C#:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct STARTUPINFOW
{
public UInt32 cb;

[MarshalAs(UnmanagedType.LPWStr)]
public String lpReserved;

[MarshalAs(UnmanagedType.LPWStr)]
public String lpDesktop;

[MarshalAs(UnmanagedType.LPWStr)]
public String lpTitle;

public UInt32 dwX;
public UInt32 dwY;
public UInt32 dwXSize;
public UInt32 dwYSize;
public UInt32 dwXCountChars;
public UInt32 dwYCountChars;
public UInt32 dwFillAttribute;
public UInt32 dwFlags;
public UInt16 wShowWindow;
public UInt16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
 
Back
Top