Re: Interop marshaling

From: Lasse Vågsæther Karlsen (lasse_at_vkarlsen.no)
Date: 12/29/04


Date: Wed, 29 Dec 2004 11:04:44 +0100

ivang wrote:
> 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;
}

-- 
Lasse Vågsæther Karlsen
http://www.vkarlsen.no/
mailto:lasse@vkarlsen.no
PGP KeyID: 0x0270466B


Relevant Pages

  • Re: How would I InterOp this structure?
    ... This is a bit tricky due to the embedded string. ... It is usually best to treat the struct as a byte array ... DWORD dwFormats; ... Public dwParams As Int32 ...
    (microsoft.public.dotnet.framework.compactframework)
  • Marshalling trouble: pointer to struct in another struct
    ... int WINAPI StartUpdate(unsigned ... typedef struct startErrorStruct ... static extern int StartUpdate(int intMode, string strTSpec, ... As you can see I'm rather new to marshalling issues, ...
    (microsoft.public.dotnet.framework.interop)
  • Problem converting string to bin/dec/hex
    ... This will require DWORD ... SetConsoleMode PROTO NEAR32 stdcall, ... OutputStr1 BYTE LF,CR,'Input string was: ... lea esi, InputAsStr ...
    (comp.lang.asm.x86)
  • Re: Is the following little function UNICODE-safe? ...
    ... static DWORD dwDefID; ... extensions and assumes it can store three characters in a DWORD, ... What does this have to do with returning a string? ... it's a static DWORD. ...
    (microsoft.public.vc.mfc)
  • Re: Is the following little function UNICODE-safe? ...
    ... static DWORD dwDefID; ... extensions and assumes it can store three characters in a DWORD, ... What does this have to do with returning a string? ... it's a static DWORD. ...
    (microsoft.public.vc.mfc)

Quantcast