Skip to content

Commit 36487da

Browse files
authored
fixed a compile-time error in type-marshalling.md (#48780)
* fixed a compile-time error in type-marshalling.md this change adds the `out` keyword to fix such compile-time error as well as inlines the variable declaration for simplicity and renames the variable from `st` to `systemTime` for both clarity and consistency. * further improved a code block in `type-marshalling.md` this change makes the code block ready-to-run for ease of use with copying.
1 parent 8e2fb40 commit 36487da

File tree

1 file changed

+23
-20
lines changed

1 file changed

+23
-20
lines changed

docs/standard/native-interop/type-marshalling.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -99,31 +99,34 @@ When you are calling methods on COM objects in .NET, the .NET runtime changes th
9999
Another aspect of type marshalling is how to pass in a struct to an unmanaged method. For instance, some of the unmanaged methods require a struct as a parameter. In these cases, you need to create a corresponding struct or a class in managed part of the world to use it as a parameter. However, just defining the class isn't enough, you also need to instruct the marshaller how to map fields in the class to the unmanaged struct. Here the `StructLayout` attribute becomes useful.
100100

101101
```csharp
102-
[LibraryImport("kernel32.dll")]
103-
static partial void GetSystemTime(out SystemTime systemTime);
102+
using System;
103+
using System.Runtime.InteropServices;
104104

105-
[StructLayout(LayoutKind.Sequential)]
106-
struct SystemTime
107-
{
108-
public ushort Year;
109-
public ushort Month;
110-
public ushort DayOfWeek;
111-
public ushort Day;
112-
public ushort Hour;
113-
public ushort Minute;
114-
public ushort Second;
115-
public ushort Millisecond;
116-
}
105+
Win32Interop.GetSystemTime(out Win32Interop.SystemTime systemTime);
106+
107+
Console.WriteLine(systemTime.Year);
117108

118-
public static void Main(string[] args)
109+
internal static partial class Win32Interop
119110
{
120-
SystemTime st = new SystemTime();
121-
GetSystemTime(st);
122-
Console.WriteLine(st.Year);
111+
[LibraryImport("kernel32.dll")]
112+
internal static partial void GetSystemTime(out SystemTime systemTime);
113+
114+
[StructLayout(LayoutKind.Sequential)]
115+
internal ref struct SystemTime
116+
{
117+
public ushort Year;
118+
public ushort Month;
119+
public ushort DayOfWeek;
120+
public ushort Day;
121+
public ushort Hour;
122+
public ushort Minute;
123+
public ushort Second;
124+
public ushort Millisecond;
125+
}
123126
}
124127
```
125128

126-
The previous code shows a simple example of calling into `GetSystemTime()` function. The interesting bit is on line 4. The attribute specifies that the fields of the class should be mapped sequentially to the struct on the other (unmanaged) side. This means that the naming of the fields isn't important, only their order is important, as it needs to correspond to the unmanaged struct, shown in the following example:
129+
The previous code shows a simple example of calling into `GetSystemTime()` function. The interesting bit is on line 13. The attribute specifies that the fields of the class should be mapped sequentially to the struct on the other (unmanaged) side. This means that the naming of the fields isn't important, only their order is important, as it needs to correspond to the unmanaged struct, shown in the following example:
127130

128131
```c
129132
typedef struct _SYSTEMTIME {
@@ -135,7 +138,7 @@ typedef struct _SYSTEMTIME {
135138
WORD wMinute;
136139
WORD wSecond;
137140
WORD wMilliseconds;
138-
} SYSTEMTIME, *PSYSTEMTIME;
141+
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
139142
```
140143

141144
Sometimes the default marshalling for your structure doesn't do what you need. The [Customizing structure marshalling](customize-struct-marshalling.md) article teaches you how to customize how your structure is marshalled.

0 commit comments

Comments
 (0)