Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
b4dd16b4
R
runtime
项目概览
dotNET Platform
/
runtime
11 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
b4dd16b4
编写于
7月 11, 2022
作者:
J
Jeremy Koritzinsky
提交者:
GitHub
7月 11, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move ArrayMarshaller and PointerArrayMarshaller to the v2 design (#71978)
上级
a3a106f4
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
371 addition
and
516 deletion
+371
-516
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
...ivate.CoreLib/src/System.Private.CoreLib.Shared.projitems
+1
-0
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs
...em/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs
+116
-125
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ContiguousCollectionMarshallerAttribute.cs
...es/Marshalling/ContiguousCollectionMarshallerAttribute.cs
+0
-0
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs
...ime/InteropServices/Marshalling/PointerArrayMarshaller.cs
+114
-127
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ArrayMarshaller.cs
...t.Interop.SourceGeneration/Marshalling/ArrayMarshaller.cs
+0
-162
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs
...Marshalling/AttributedMarshallingModelGeneratorFactory.cs
+30
-27
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs
...eGeneration/Marshalling/MarshallingGeneratorExtensions.cs
+14
-7
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StatefulMarshallingStrategy.cs
...urceGeneration/Marshalling/StatefulMarshallingStrategy.cs
+6
-4
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StatelessMarshallingStrategy.cs
...rceGeneration/Marshalling/StatelessMarshallingStrategy.cs
+6
-4
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs
...soft.Interop.SourceGeneration/MarshallingAttributeInfo.cs
+6
-18
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs
...vices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs
+6
-2
src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs
...ime.InteropServices/ref/System.Runtime.InteropServices.cs
+72
-40
未找到文件。
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
浏览文件 @
b4dd16b4
...
...
@@ -875,6 +875,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\AnsiStringMarshaller.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\ArrayMarshaller.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\BStrStringMarshaller.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\ContiguousCollectionMarshallerAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomMarshallerAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerDirection.cs" />
...
...
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs
浏览文件 @
b4dd16b4
...
...
@@ -10,147 +10,138 @@ namespace System.Runtime.InteropServices.Marshalling
/// Marshaller for arrays
/// </summary>
/// <typeparam name="T">Array element type</typeparam>
/// <typeparam name="TUnmanagedElement">The unmanaged type for the element type</typeparam>
[
CLSCompliant
(
false
)]
[
CustomTypeMarshaller
(
typeof
(
CustomTypeMarshallerAttribute
.
GenericPlaceholder
[]),
CustomTypeMarshallerKind
.
LinearCollection
,
BufferSize
=
0x200
,
Features
=
CustomTypeMarshallerFeatures
.
UnmanagedResources
|
CustomTypeMarshallerFeatures
.
CallerAllocatedBuffer
|
CustomTypeMarshallerFeatures
.
TwoStageMarshalling
)]
public
unsafe
ref
struct
ArrayMarshaller
<
T
>
[
CustomMarshaller
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
[]),
MarshalMode
.
Default
,
typeof
(
ArrayMarshaller
<,>))]
[
CustomMarshaller
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
[]),
MarshalMode
.
ManagedToUnmanagedIn
,
typeof
(
ArrayMarshaller
<,>.
ManagedToUnmanagedIn
))]
[
ContiguousCollectionMarshaller
]
public
static
unsafe
class
ArrayMarshaller
<
T
,
TUnmanagedElement
>
where
TUnmanagedElement
:
unmanaged
{
private
readonly
int
_sizeOfNativeElement
;
private
T
[]?
_managedArray
;
private
IntPtr
_allocatedMemory
;
private
Span
<
byte
>
_span
;
/// <summary>
/// Initializes a new instance of the <see cref="ArrayMarshaller{T}"/>.
/// </summary>
/// <param name="sizeOfNativeElement">Size of the native element in bytes.</param>
public
ArrayMarshaller
(
int
sizeOfNativeElement
)
:
this
()
public
static
TUnmanagedElement
*
AllocateContainerForUnmanagedElements
(
T
[]?
managed
,
out
int
numElements
)
{
_sizeOfNativeElement
=
sizeOfNativeElement
;
}
/// <summary>
/// Initializes a new instance of the <see cref="ArrayMarshaller{T}"/>.
/// </summary>
/// <param name="array">Array to be marshalled.</param>
/// <param name="sizeOfNativeElement">Size of the native element in bytes.</param>
public
ArrayMarshaller
(
T
[]?
array
,
int
sizeOfNativeElement
)
:
this
(
array
,
Span
<
byte
>.
Empty
,
sizeOfNativeElement
)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ArrayMarshaller{T}"/>.
/// </summary>
/// <param name="array">Array to be marshalled.</param>
/// <param name="buffer">Buffer that may be used for marshalling.</param>
/// <param name="sizeOfNativeElement">Size of the native element in bytes.</param>
/// <remarks>
/// The <paramref name="buffer"/> must not be movable - that is, it should not be
/// on the managed heap or it should be pinned.
/// </remarks>
/// <seealso cref="CustomTypeMarshallerFeatures.CallerAllocatedBuffer"/>
public
ArrayMarshaller
(
T
[]?
array
,
Span
<
byte
>
buffer
,
int
sizeOfNativeElement
)
{
_allocatedMemory
=
default
;
_sizeOfNativeElement
=
sizeOfNativeElement
;
if
(
array
is
null
)
if
(
managed
is
null
)
{
_managedArray
=
null
;
_span
=
default
;
return
;
numElements
=
0
;
return
null
;
}
_managedArray
=
array
;
numElements
=
managed
.
Length
;
// Always allocate at least one byte when the array is zero-length.
int
bufferSize
=
checked
(
array
.
Length
*
_sizeOfNativeElement
);
int
spaceToAllocate
=
Math
.
Max
(
bufferSize
,
1
);
if
(
spaceToAllocate
<=
buffer
.
Length
)
{
_span
=
buffer
[
0.
.
spaceToAllocate
];
}
else
{
_allocatedMemory
=
Marshal
.
AllocCoTaskMem
(
spaceToAllocate
);
_span
=
new
Span
<
byte
>((
void
*)
_allocatedMemory
,
spaceToAllocate
);
}
int
spaceToAllocate
=
Math
.
Max
(
checked
(
sizeof
(
TUnmanagedElement
)
*
numElements
),
1
);
return
(
TUnmanagedElement
*)
Marshal
.
AllocCoTaskMem
(
spaceToAllocate
);
}
/// <summary>
/// Gets a span that points to the memory where the managed values of the array are stored.
/// </summary>
/// <returns>Span over managed values of the array.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.In"/>
public
ReadOnlySpan
<
T
>
GetManagedValuesSource
()
=>
_managedArray
;
/// <summary>
/// Gets a span that points to the memory where the unmarshalled managed values of the array should be stored.
/// </summary>
/// <param name="length">Length of the array.</param>
/// <returns>Span where managed values of the array should be stored.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.Out"/>
public
Span
<
T
>
GetManagedValuesDestination
(
int
length
)
=>
_allocatedMemory
==
IntPtr
.
Zero
?
null
:
_managedArray
=
new
T
[
length
];
/// <summary>
/// Returns a span that points to the memory where the native values of the array are stored after the native call.
/// </summary>
/// <param name="length">Length of the array.</param>
/// <returns>Span over the native values of the array.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.Out"/>
public
ReadOnlySpan
<
byte
>
GetNativeValuesSource
(
int
length
)
{
if
(
_allocatedMemory
==
IntPtr
.
Zero
)
return
default
;
public
static
ReadOnlySpan
<
T
>
GetManagedValuesSource
(
T
[]?
managed
)
=>
managed
;
int
allocatedSize
=
checked
(
length
*
_sizeOfNativeElement
);
_span
=
new
Span
<
byte
>((
void
*)
_allocatedMemory
,
allocatedSize
);
return
_span
;
}
public
static
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
=>
new
Span
<
TUnmanagedElement
>(
unmanaged
,
numElements
);
/// <summary>
/// Returns a span that points to the memory where the native values of the array should be stored.
/// </summary>
/// <returns>Span where native values of the array should be stored.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.In"/>
public
Span
<
byte
>
GetNativeValuesDestination
()
=>
_span
;
/// <summary>
/// Returns a reference to the marshalled array.
/// </summary>
public
ref
byte
GetPinnableReference
()
=>
ref
MemoryMarshal
.
GetReference
(
_span
);
/// <summary>
/// Returns the native value representing the array.
/// </summary>
/// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/>
public
byte
*
ToNativeValue
()
=>
(
byte
*)
Unsafe
.
AsPointer
(
ref
GetPinnableReference
());
/// <summary>
/// Sets the native value representing the array.
/// </summary>
/// <param name="value">The native value.</param>
/// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/>
public
void
FromNativeValue
(
byte
*
value
)
public
static
T
[]?
AllocateContainerForManagedElements
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
{
_allocatedMemory
=
(
IntPtr
)
value
;
if
(
unmanaged
is
null
)
return
null
;
return
new
T
[
numElements
];
}
/// <summary>
/// Returns the managed array.
/// </summary>
/// <seealso cref="CustomTypeMarshallerDirection.Out"/>
public
T
[]?
ToManaged
()
=>
_managedArray
;
/// <summary>
/// Frees native resources.
/// </summary>
/// <seealso cref="CustomTypeMarshallerFeatures.UnmanagedResources"/>
public
void
FreeNative
()
public
static
Span
<
T
>
GetManagedValuesDestination
(
T
[]?
managed
)
=>
managed
;
public
static
ReadOnlySpan
<
TUnmanagedElement
>
GetUnmanagedValuesSource
(
TUnmanagedElement
*
unmanagedValue
,
int
numElements
)
=>
new
ReadOnlySpan
<
TUnmanagedElement
>(
unmanagedValue
,
numElements
);
public
static
void
Free
(
TUnmanagedElement
*
unmanaged
)
=>
Marshal
.
FreeCoTaskMem
((
IntPtr
)
unmanaged
);
public
ref
struct
ManagedToUnmanagedIn
{
Marshal
.
FreeCoTaskMem
(
_allocatedMemory
);
// We'll keep the buffer size at a maximum of 200 bytes to avoid overflowing the stack.
public
static
int
BufferSize
{
get
;
}
=
0x200
/
sizeof
(
TUnmanagedElement
);
private
T
[]?
_managedArray
;
private
TUnmanagedElement
*
_allocatedMemory
;
private
Span
<
TUnmanagedElement
>
_span
;
/// <summary>
/// Initializes the <see cref="ArrayMarshaller{T, TUnmanagedElement}.ManagedToUnmanagedIn"/> marshaller.
/// </summary>
/// <param name="array">Array to be marshalled.</param>
/// <param name="buffer">Buffer that may be used for marshalling.</param>
/// <remarks>
/// The <paramref name="buffer"/> must not be movable - that is, it should not be
/// on the managed heap or it should be pinned.
/// </remarks>
public
void
FromManaged
(
T
[]?
array
,
Span
<
TUnmanagedElement
>
buffer
)
{
_allocatedMemory
=
null
;
if
(
array
is
null
)
{
_managedArray
=
null
;
_span
=
default
;
return
;
}
_managedArray
=
array
;
// Always allocate at least one byte when the array is zero-length.
if
(
array
.
Length
<=
buffer
.
Length
)
{
_span
=
buffer
[
0.
.
array
.
Length
];
}
else
{
int
bufferSize
=
checked
(
array
.
Length
*
sizeof
(
TUnmanagedElement
));
int
spaceToAllocate
=
Math
.
Max
(
bufferSize
,
1
);
_allocatedMemory
=
(
TUnmanagedElement
*)
NativeMemory
.
Alloc
((
nuint
)
spaceToAllocate
);
_span
=
new
Span
<
TUnmanagedElement
>(
_allocatedMemory
,
array
.
Length
);
}
}
/// <summary>
/// Gets a span that points to the memory where the managed values of the array are stored.
/// </summary>
/// <returns>Span over managed values of the array.</returns>
public
ReadOnlySpan
<
T
>
GetManagedValuesSource
()
=>
_managedArray
;
/// <summary>
/// Returns a span that points to the memory where the unmanaged values of the array should be stored.
/// </summary>
/// <returns>Span where unmanaged values of the array should be stored.</returns>
public
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
()
=>
_span
;
/// <summary>
/// Returns a reference to the marshalled array.
/// </summary>
public
ref
TUnmanagedElement
GetPinnableReference
()
=>
ref
MemoryMarshal
.
GetReference
(
_span
);
/// <summary>
/// Returns the unmanaged value representing the array.
/// </summary>
public
TUnmanagedElement
*
ToUnmanaged
()
=>
(
TUnmanagedElement
*)
Unsafe
.
AsPointer
(
ref
GetPinnableReference
());
/// <summary>
/// Frees resources.
/// </summary>
public
void
Free
()
{
NativeMemory
.
Free
(
_allocatedMemory
);
}
public
static
ref
T
GetPinnableReference
(
T
[]?
array
)
{
if
(
array
is
null
)
{
return
ref
Unsafe
.
NullRef
<
T
>();
}
return
ref
MemoryMarshal
.
GetArrayDataReference
(
array
);
}
}
}
}
src/libraries/System.
Runtime.InteropServices/tests/Ancillary.Interop
/ContiguousCollectionMarshallerAttribute.cs
→
src/libraries/System.
Private.CoreLib/src/System/Runtime/InteropServices/Marshalling
/ContiguousCollectionMarshallerAttribute.cs
浏览文件 @
b4dd16b4
文件已移动
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs
浏览文件 @
b4dd16b4
...
...
@@ -10,151 +10,138 @@ namespace System.Runtime.InteropServices.Marshalling
/// Marshaller for arrays of pointers
/// </summary>
/// <typeparam name="T">Array element pointer type</typeparam>
/// <typeparam name="TUnmanagedElement">The unmanaged type for the element pointer type</typeparam>
[
CLSCompliant
(
false
)]
[
CustomTypeMarshaller
(
typeof
(
CustomTypeMarshallerAttribute
.
GenericPlaceholder
*[]),
CustomTypeMarshallerKind
.
LinearCollection
,
BufferSize
=
0x200
,
Features
=
CustomTypeMarshallerFeatures
.
UnmanagedResources
|
CustomTypeMarshallerFeatures
.
CallerAllocatedBuffer
|
CustomTypeMarshallerFeatures
.
TwoStageMarshalling
)]
public
unsafe
ref
struct
PointerArrayMarshaller
<
T
>
where
T
:
unmanaged
[
CustomMarshaller
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
*[]),
MarshalMode
.
Default
,
typeof
(
PointerArrayMarshaller
<,>))]
[
CustomMarshaller
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
*[]),
MarshalMode
.
ManagedToUnmanagedIn
,
typeof
(
PointerArrayMarshaller
<,>.
ManagedToUnmanagedIn
))]
[
ContiguousCollectionMarshaller
]
public
static
unsafe
class
PointerArrayMarshaller
<
T
,
TUnmanagedElement
>
where
T
:
unmanaged
where
TUnmanagedElement
:
unmanaged
{
private
readonly
int
_sizeOfNativeElement
;
private
T
*[]?
_managedArray
;
private
IntPtr
_allocatedMemory
;
private
Span
<
byte
>
_span
;
/// <summary>
/// Initializes a new instance of the <see cref="PointerArrayMarshaller{T}"/>.
/// </summary>
/// <param name="sizeOfNativeElement">Size of the native element in bytes.</param>
public
PointerArrayMarshaller
(
int
sizeOfNativeElement
)
:
this
()
public
static
TUnmanagedElement
*
AllocateContainerForUnmanagedElements
(
T
*[]?
managed
,
out
int
numElements
)
{
_sizeOfNativeElement
=
sizeOfNativeElement
;
}
/// <summary>
/// Initializes a new instance of the <see cref="PointerArrayMarshaller{T}"/>.
/// </summary>
/// <param name="array">Array to be marshalled.</param>
/// <param name="sizeOfNativeElement">Size of the native element in bytes.</param>
public
PointerArrayMarshaller
(
T
*[]?
array
,
int
sizeOfNativeElement
)
:
this
(
array
,
Span
<
byte
>.
Empty
,
sizeOfNativeElement
)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="PointerArrayMarshaller{T}"/>.
/// </summary>
/// <param name="array">Array to be marshalled.</param>
/// <param name="buffer">Buffer that may be used for marshalling.</param>
/// <param name="sizeOfNativeElement">Size of the native element in bytes.</param>
/// <remarks>
/// The <paramref name="buffer"/> must not be movable - that is, it should not be
/// on the managed heap or it should be pinned.
/// </remarks>
/// <seealso cref="CustomTypeMarshallerFeatures.CallerAllocatedBuffer"/>
public
PointerArrayMarshaller
(
T
*[]?
array
,
Span
<
byte
>
buffer
,
int
sizeOfNativeElement
)
{
_allocatedMemory
=
default
;
_sizeOfNativeElement
=
sizeOfNativeElement
;
if
(
array
is
null
)
if
(
managed
is
null
)
{
_managedArray
=
null
;
_span
=
default
;
return
;
numElements
=
0
;
return
null
;
}
_managedArray
=
array
;
numElements
=
managed
.
Length
;
// Always allocate at least one byte when the array is zero-length.
int
bufferSize
=
checked
(
array
.
Length
*
_sizeOfNativeElement
);
int
spaceToAllocate
=
Math
.
Max
(
bufferSize
,
1
);
if
(
spaceToAllocate
<=
buffer
.
Length
)
{
_span
=
buffer
[
0.
.
spaceToAllocate
];
}
else
{
_allocatedMemory
=
Marshal
.
AllocCoTaskMem
(
spaceToAllocate
);
_span
=
new
Span
<
byte
>((
void
*)
_allocatedMemory
,
spaceToAllocate
);
}
int
spaceToAllocate
=
Math
.
Max
(
checked
(
sizeof
(
TUnmanagedElement
)
*
numElements
),
1
);
return
(
TUnmanagedElement
*)
Marshal
.
AllocCoTaskMem
(
spaceToAllocate
);
}
/// <summary>
/// Gets a span that points to the memory where the managed values of the array are stored.
/// </summary>
/// <returns>Span over managed values of the array.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.In"/>
public
ReadOnlySpan
<
IntPtr
>
GetManagedValuesSource
()
=>
Unsafe
.
As
<
IntPtr
[
]>
(
_managedArray
);
/// <summary>
/// Gets a span that points to the memory where the unmarshalled managed values of the array should be stored.
/// </summary>
/// <param name="length">Length of the array.</param>
/// <returns>Span where managed values of the array should be stored.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.Out"/>
public
Span
<
IntPtr
>
GetManagedValuesDestination
(
int
length
)
public
static
ReadOnlySpan
<
IntPtr
>
GetManagedValuesSource
(
T
*[]?
managed
)
=>
Unsafe
.
As
<
IntPtr
[
]>
(
managed
);
public
static
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
=>
new
Span
<
TUnmanagedElement
>(
unmanaged
,
numElements
);
public
static
T
*[]?
AllocateContainerForManagedElements
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
{
if
(
_allocatedMemory
==
IntPtr
.
Zero
)
if
(
unmanaged
is
null
)
return
null
;
_managedArray
=
new
T
*[
length
];
return
Unsafe
.
As
<
IntPtr
[
]>
(
_managedArray
);
return
new
T
*[
numElements
];
}
/// <summary>
/// Returns a span that points to the memory where the native values of the array are stored after the native call.
/// </summary>
/// <param name="length">Length of the array.</param>
/// <returns>Span over the native values of the array.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.Out"/>
public
ReadOnlySpan
<
byte
>
GetNativeValuesSource
(
int
length
)
{
if
(
_allocatedMemory
==
IntPtr
.
Zero
)
return
default
;
public
static
Span
<
IntPtr
>
GetManagedValuesDestination
(
T
*[]?
managed
)
=>
Unsafe
.
As
<
IntPtr
[
]>
(
managed
);
int
allocatedSize
=
checked
(
length
*
_sizeOfNativeElement
);
_span
=
new
Span
<
byte
>((
void
*)
_allocatedMemory
,
allocatedSize
);
return
_span
;
}
public
static
ReadOnlySpan
<
TUnmanagedElement
>
GetUnmanagedValuesSource
(
TUnmanagedElement
*
unmanagedValue
,
int
numElements
)
=>
new
ReadOnlySpan
<
TUnmanagedElement
>(
unmanagedValue
,
numElements
);
public
static
void
Free
(
TUnmanagedElement
*
unmanaged
)
=>
Marshal
.
FreeCoTaskMem
((
IntPtr
)
unmanaged
);
/// <summary>
/// Returns a span that points to the memory where the native values of the array should be stored.
/// </summary>
/// <returns>Span where native values of the array should be stored.</returns>
/// <seealso cref="CustomTypeMarshallerDirection.In"/>
public
Span
<
byte
>
GetNativeValuesDestination
()
=>
_span
;
/// <summary>
/// Returns a reference to the marshalled array.
/// </summary>
public
ref
byte
GetPinnableReference
()
=>
ref
MemoryMarshal
.
GetReference
(
_span
);
/// <summary>
/// Returns the native value representing the array.
/// </summary>
/// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/>
public
byte
*
ToNativeValue
()
=>
(
byte
*)
Unsafe
.
AsPointer
(
ref
GetPinnableReference
());
/// <summary>
/// Sets the native value representing the array.
/// </summary>
/// <param name="value">The native value.</param>
/// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/>
public
void
FromNativeValue
(
byte
*
value
)
=>
_allocatedMemory
=
(
IntPtr
)
value
;
/// <summary>
/// Returns the managed array.
/// </summary>
/// <seealso cref="CustomTypeMarshallerDirection.Out"/>
public
T
*[]?
ToManaged
()
=>
_managedArray
;
/// <summary>
/// Frees native resources.
/// </summary>
/// <seealso cref="CustomTypeMarshallerFeatures.UnmanagedResources"/>
public
void
FreeNative
()
public
ref
struct
ManagedToUnmanagedIn
{
Marshal
.
FreeCoTaskMem
(
_allocatedMemory
);
public
static
int
BufferSize
=>
0x200
/
sizeof
(
TUnmanagedElement
);
private
T
*[]?
_managedArray
;
private
TUnmanagedElement
*
_allocatedMemory
;
private
Span
<
TUnmanagedElement
>
_span
;
/// <summary>
/// Initializes the <see cref="PointerArrayMarshaller{T, TUnmanagedElement}.ManagedToUnmanagedIn"/> marshaller.
/// </summary>
/// <param name="array">Array to be marshalled.</param>
/// <param name="buffer">Buffer that may be used for marshalling.</param>
/// <remarks>
/// The <paramref name="buffer"/> must not be movable - that is, it should not be
/// on the managed heap or it should be pinned.
/// </remarks>
public
void
FromManaged
(
T
*[]?
array
,
Span
<
TUnmanagedElement
>
buffer
)
{
_allocatedMemory
=
null
;
if
(
array
is
null
)
{
_managedArray
=
null
;
_span
=
default
;
return
;
}
_managedArray
=
array
;
// Always allocate at least one byte when the array is zero-length.
if
(
array
.
Length
<=
buffer
.
Length
)
{
_span
=
buffer
[
0.
.
array
.
Length
];
}
else
{
int
bufferSize
=
checked
(
array
.
Length
*
sizeof
(
TUnmanagedElement
));
int
spaceToAllocate
=
Math
.
Max
(
bufferSize
,
1
);
_allocatedMemory
=
(
TUnmanagedElement
*)
NativeMemory
.
Alloc
((
nuint
)
spaceToAllocate
);
_span
=
new
Span
<
TUnmanagedElement
>(
_allocatedMemory
,
array
.
Length
);
}
}
/// <summary>
/// Gets a span that points to the memory where the managed values of the array are stored.
/// </summary>
/// <returns>Span over managed values of the array.</returns>
public
ReadOnlySpan
<
IntPtr
>
GetManagedValuesSource
()
=>
Unsafe
.
As
<
IntPtr
[
]>
(
_managedArray
);
/// <summary>
/// Returns a span that points to the memory where the unmanaged values of the array should be stored.
/// </summary>
/// <returns>Span where unmanaged values of the array should be stored.</returns>
public
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
()
=>
_span
;
/// <summary>
/// Returns a reference to the marshalled array.
/// </summary>
public
ref
TUnmanagedElement
GetPinnableReference
()
=>
ref
MemoryMarshal
.
GetReference
(
_span
);
/// <summary>
/// Returns the unmanaged value representing the array.
/// </summary>
public
TUnmanagedElement
*
ToUnmanaged
()
=>
(
TUnmanagedElement
*)
Unsafe
.
AsPointer
(
ref
GetPinnableReference
());
/// <summary>
/// Frees resources.
/// </summary>
public
void
Free
()
{
NativeMemory
.
Free
(
_allocatedMemory
);
}
public
static
ref
byte
GetPinnableReference
(
T
*[]?
array
)
{
if
(
array
is
null
)
{
return
ref
Unsafe
.
NullRef
<
byte
>();
}
return
ref
MemoryMarshal
.
GetArrayDataReference
(
array
);
}
}
}
}
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ArrayMarshaller.cs
已删除
100644 → 0
浏览文件 @
a3a106f4
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using
System
;
using
System.Collections.Generic
;
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.CSharp
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
static
Microsoft
.
CodeAnalysis
.
CSharp
.
SyntaxFactory
;
namespace
Microsoft.Interop
{
public
sealed
class
ArrayMarshaller
:
IMarshallingGenerator
{
private
readonly
IMarshallingGenerator
_manualMarshallingGenerator
;
private
readonly
TypePositionInfo
_elementInfo
;
private
readonly
bool
_enablePinning
;
public
ArrayMarshaller
(
IMarshallingGenerator
manualMarshallingGenerator
,
TypePositionInfo
elementInfo
,
bool
enablePinning
)
{
_manualMarshallingGenerator
=
manualMarshallingGenerator
;
_elementInfo
=
elementInfo
;
_enablePinning
=
enablePinning
;
}
public
bool
IsSupported
(
TargetFramework
target
,
Version
version
)
{
return
target
is
TargetFramework
.
Net
&&
version
.
Major
>=
7
;
}
public
ValueBoundaryBehavior
GetValueBoundaryBehavior
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
if
(
IsPinningPathSupported
(
info
,
context
))
{
if
(
AsNativeType
(
info
)
is
PointerTypeSyntax
pointerType
&&
pointerType
.
ElementType
is
PredefinedTypeSyntax
predefinedType
&&
predefinedType
.
Keyword
.
IsKind
(
SyntaxKind
.
VoidKeyword
))
{
return
ValueBoundaryBehavior
.
NativeIdentifier
;
}
// Cast to native type if it is not void*
return
ValueBoundaryBehavior
.
CastNativeIdentifier
;
}
return
_manualMarshallingGenerator
.
GetValueBoundaryBehavior
(
info
,
context
);
}
public
TypeSyntax
AsNativeType
(
TypePositionInfo
info
)
{
return
_manualMarshallingGenerator
.
AsNativeType
(
info
);
}
public
SignatureBehavior
GetNativeSignatureBehavior
(
TypePositionInfo
info
)
{
return
_manualMarshallingGenerator
.
GetNativeSignatureBehavior
(
info
);
}
public
IEnumerable
<
StatementSyntax
>
Generate
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
if
(
IsPinningPathSupported
(
info
,
context
))
{
return
GeneratePinningPath
(
info
,
context
);
}
return
_manualMarshallingGenerator
.
Generate
(
info
,
context
);
}
public
bool
SupportsByValueMarshalKind
(
ByValueContentsMarshalKind
marshalKind
,
StubCodeContext
context
)
{
if
(
context
.
SingleFrameSpansNativeContext
&&
_enablePinning
)
{
// Only report no support for by-value contents when element is strictly blittable, such that
// the status remains the same regardless of whether or not runtime marshalling is enabled
if
(
_elementInfo
.
MarshallingAttributeInfo
is
NoMarshallingInfo
||
_elementInfo
.
MarshallingAttributeInfo
is
UnmanagedBlittableMarshallingInfo
{
IsStrictlyBlittable
:
true
}
||
_elementInfo
.
MarshallingAttributeInfo
is
NativeMarshallingAttributeInfo_V1
{
IsStrictlyBlittable
:
true
})
{
return
false
;
}
}
return
marshalKind
.
HasFlag
(
ByValueContentsMarshalKind
.
Out
);
}
public
bool
UsesNativeIdentifier
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
if
(
IsPinningPathSupported
(
info
,
context
))
{
return
false
;
}
return
_manualMarshallingGenerator
.
UsesNativeIdentifier
(
info
,
context
);
}
private
bool
IsPinningPathSupported
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
return
context
.
SingleFrameSpansNativeContext
&&
_enablePinning
&&
!
info
.
IsByRef
&&
!
info
.
IsManagedReturnPosition
;
}
private
IEnumerable
<
StatementSyntax
>
GeneratePinningPath
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
(
string
managedIdentifer
,
string
nativeIdentifier
)
=
context
.
GetIdentifiers
(
info
);
string
byRefIdentifier
=
$"__byref_
{
managedIdentifer
}
"
;
// The element type here is used only for refs/pointers. In the pointer array case, we use byte as the basic placeholder type,
// since we can't use pointer types in generic type parameters.
bool
isPointerArray
=
info
.
ManagedType
is
SzArrayType
arrayType
&&
arrayType
.
ElementTypeInfo
is
PointerTypeInfo
;
TypeSyntax
arrayElementType
=
isPointerArray
?
PredefinedType
(
Token
(
SyntaxKind
.
ByteKeyword
))
:
_elementInfo
.
ManagedType
.
Syntax
;
if
(
context
.
CurrentStage
==
StubCodeContext
.
Stage
.
Marshal
)
{
// [COMPAT] We use explicit byref calculations here instead of just using a fixed statement
// since a fixed statement converts a zero-length array to a null pointer.
// Many native APIs, such as GDI+, ICU, etc. validate that an array parameter is non-null
// even when the passed in array length is zero. To avoid breaking customers that want to move
// to source-generated interop in subtle ways, we explicitly pass a reference to the 0-th element
// of an array as long as it is non-null, matching the behavior of the built-in interop system
// for single-dimensional zero-based arrays.
// ref <elementType> <byRefIdentifier> = ref <managedIdentifer> == null ? ref *(<elementType>*)0 : ref MemoryMarshal.GetArrayDataReference(<managedIdentifer>);
PrefixUnaryExpressionSyntax
nullRef
=
PrefixUnaryExpression
(
SyntaxKind
.
PointerIndirectionExpression
,
CastExpression
(
PointerType
(
arrayElementType
),
LiteralExpression
(
SyntaxKind
.
NumericLiteralExpression
,
Literal
(
0
))));
InvocationExpressionSyntax
getArrayDataReference
=
InvocationExpression
(
MemberAccessExpression
(
SyntaxKind
.
SimpleMemberAccessExpression
,
ParseTypeName
(
TypeNames
.
System_Runtime_InteropServices_MemoryMarshal
),
IdentifierName
(
"GetArrayDataReference"
)),
ArgumentList
(
SingletonSeparatedList
(
Argument
(
IdentifierName
(
managedIdentifer
)))));
yield
return
LocalDeclarationStatement
(
VariableDeclaration
(
RefType
(
arrayElementType
))
.
WithVariables
(
SingletonSeparatedList
(
VariableDeclarator
(
Identifier
(
byRefIdentifier
))
.
WithInitializer
(
EqualsValueClause
(
RefExpression
(
ParenthesizedExpression
(
ConditionalExpression
(
BinaryExpression
(
SyntaxKind
.
EqualsExpression
,
IdentifierName
(
managedIdentifer
),
LiteralExpression
(
SyntaxKind
.
NullLiteralExpression
)),
RefExpression
(
nullRef
),
RefExpression
(
getArrayDataReference
)))))))));
}
if
(
context
.
CurrentStage
==
StubCodeContext
.
Stage
.
Pin
)
{
// fixed (void* <nativeIdentifier> = &<byRefIdentifier>)
yield
return
FixedStatement
(
VariableDeclaration
(
PointerType
(
PredefinedType
(
Token
(
SyntaxKind
.
VoidKeyword
))),
SingletonSeparatedList
(
VariableDeclarator
(
Identifier
(
nativeIdentifier
))
.
WithInitializer
(
EqualsValueClause
(
PrefixUnaryExpression
(
SyntaxKind
.
AddressOfExpression
,
IdentifierName
(
byRefIdentifier
)))))),
EmptyStatement
());
}
}
}
}
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs
浏览文件 @
b4dd16b4
...
...
@@ -299,16 +299,15 @@ private IMarshallingGenerator CreateCustomNativeTypeMarshaller(TypePositionInfo
// Insert the unmanaged element type into the marshaller type
TypeSyntax
unmanagedElementType
=
elementMarshaller
.
AsNativeType
(
elementInfo
).
GetCompatibleGenericTypeParameterSyntax
();
TypeSyntax
marshallerTypeSyntax
=
marshallerData
.
MarshallerType
.
Syntax
;
marshallerTypeSyntax
=
marshallerTypeSyntax
.
ReplaceNodes
(
marshallerTypeSyntax
.
DescendantNodesAndSelf
().
OfType
<
TypeSyntax
>().
Where
(
t
=>
t
.
IsEquivalentTo
(
marshalInfo
.
PlaceholderTypeParameter
.
Syntax
)),
(
_
,
_
)
=>
unmanagedElementType
);
marshallerTypeSyntax
=
ReplacePlaceholderSyntaxWithUnmanagedTypeSyntax
(
marshallerTypeSyntax
,
marshalInfo
,
unmanagedElementType
);
TypeSyntax
nativeTypeSyntax
=
ReplacePlaceholderSyntaxWithUnmanagedTypeSyntax
(
marshallerData
.
NativeType
.
Syntax
,
marshalInfo
,
unmanagedElementType
);
ICustomTypeMarshallingStrategy
marshallingStrategy
;
bool
elementIsBlittable
=
elementMarshaller
is
BlittableMarshaller
;
if
(
marshallerData
.
HasState
)
{
marshallingStrategy
=
new
StatefulValueMarshalling
(
marshallerTypeSyntax
,
marshallerData
.
NativeType
.
Syntax
,
marshallerData
.
Shape
);
marshallingStrategy
=
new
StatefulValueMarshalling
(
marshallerTypeSyntax
,
nativeType
Syntax
,
marshallerData
.
Shape
);
if
(
marshallerData
.
Shape
.
HasFlag
(
MarshallerShape
.
CallerAllocatedBuffer
))
{
// Check if the buffer element type is actually the unmanaged element type
...
...
@@ -331,39 +330,51 @@ private IMarshallingGenerator CreateCustomNativeTypeMarshaller(TypePositionInfo
{
if
(
elementIsBlittable
)
{
marshallingStrategy
=
new
StatelessLinearCollectionBlittableElementsMarshalling
(
marshallerTypeSyntax
,
marshallerData
.
NativeType
.
Syntax
,
marshallerData
.
Shape
,
marshallerData
.
CollectionElementType
.
Syntax
,
unmanagedElementType
,
numElementsExpression
);
marshallingStrategy
=
new
StatelessLinearCollectionBlittableElementsMarshalling
(
marshallerTypeSyntax
,
nativeType
Syntax
,
marshallerData
.
Shape
,
marshallerData
.
CollectionElementType
.
Syntax
,
unmanagedElementType
,
numElementsExpression
);
}
else
{
marshallingStrategy
=
new
StatelessLinearCollectionNonBlittableElementsMarshalling
(
marshallerTypeSyntax
,
marshallerData
.
NativeType
.
Syntax
,
marshallerData
.
Shape
,
unmanagedElementType
,
elementMarshaller
,
elementInfo
,
numElementsExpression
);
marshallingStrategy
=
new
StatelessLinearCollectionNonBlittableElementsMarshalling
(
marshallerTypeSyntax
,
nativeType
Syntax
,
marshallerData
.
Shape
,
unmanagedElementType
,
elementMarshaller
,
elementInfo
,
numElementsExpression
);
}
if
(
marshallerData
.
Shape
.
HasFlag
(
MarshallerShape
.
Free
))
marshallingStrategy
=
new
StatelessFreeMarshalling
(
marshallingStrategy
,
marshallerTypeSyntax
);
}
IMarshallingGenerator
marshallingGenerator
=
new
CustomNativeTypeMarshallingGenerator
(
marshallingStrategy
,
enableByValueContentsMarshalling
:
info
.
ManagedType
is
SzArrayType
&&
(!
elementIsBlittable
||
ElementTypeIsSometimesNonBlittable
(
elementInfo
)));
if
(
marshalInfo
.
UseDefaultMarshalling
&&
info
.
ManagedType
is
SzArrayType
)
{
return
new
ArrayMarshaller
(
new
CustomNativeTypeMarshallingGenerator
(
marshallingStrategy
,
enableByValueContentsMarshalling
:
true
),
elementInfo
,
elementIsBlittable
);
}
IMarshallingGenerator
marshallingGenerator
=
new
CustomNativeTypeMarshallingGenerator
(
marshallingStrategy
,
enableByValueContentsMarshalling
:
false
);
if
(
marshallerData
.
Shape
.
HasFlag
(
MarshallerShape
.
StatelessPinnableReference
))
// Elements in the collection must be blittable to use the pinnable marshaller.
if
(
marshallerData
.
Shape
.
HasFlag
(
MarshallerShape
.
StatelessPinnableReference
)
&&
elementIsBlittable
)
{
marshallingGenerator
=
new
StaticPinnableManagedValueMarshaller
(
marshallingGenerator
,
marshallerTypeSyntax
);
}
// Elements in the collection must be blittable to use the pinnable marshaller.
return
marshalInfo
.
IsPinnableManagedType
&&
elementIsBlittable
?
new
PinnableManagedValueMarshaller
(
marshallingGenerator
)
:
marshallingGenerator
;
:
marshallingGenerator
;
}
private
static
bool
ElementTypeIsSometimesNonBlittable
(
TypePositionInfo
elementInfo
)
{
if
(
elementInfo
.
MarshallingAttributeInfo
is
NoMarshallingInfo
||
elementInfo
.
MarshallingAttributeInfo
is
UnmanagedBlittableMarshallingInfo
{
IsStrictlyBlittable
:
true
}
||
elementInfo
.
MarshallingAttributeInfo
is
NativeMarshallingAttributeInfo_V1
{
IsStrictlyBlittable
:
true
})
{
return
false
;
}
return
true
;
}
private
static
TypeSyntax
ReplacePlaceholderSyntaxWithUnmanagedTypeSyntax
(
TypeSyntax
originalTypeSyntax
,
NativeLinearCollectionMarshallingInfo
marshalInfo
,
TypeSyntax
unmanagedElementType
)
=>
originalTypeSyntax
.
ReplaceNodes
(
originalTypeSyntax
.
DescendantNodesAndSelf
().
OfType
<
TypeSyntax
>().
Where
(
t
=>
t
.
IsEquivalentTo
(
marshalInfo
.
PlaceholderTypeParameter
.
Syntax
)),
(
_
,
_
)
=>
unmanagedElementType
);
private
void
ValidateCustomNativeTypeMarshallingSupported
(
TypePositionInfo
info
,
StubCodeContext
context
,
NativeMarshallingAttributeInfo
marshalInfo
)
{
// Marshalling out or return parameter, but no out marshaller is specified
...
...
@@ -550,14 +561,6 @@ private static void ValidateCustomNativeTypeMarshallingSupported_V1(TypePosition
marshallingStrategy
,
SizeOfExpression
(
nativeElementType
));
if
(
collectionInfo
.
UseDefaultMarshalling
&&
info
.
ManagedType
is
SzArrayType
)
{
return
new
ArrayMarshaller
(
new
CustomNativeTypeMarshallingGenerator
(
marshallingStrategy
,
enableByValueContentsMarshalling
:
true
),
elementInfo
,
elementIsBlittable
);
}
IMarshallingGenerator
marshallingGenerator
=
new
CustomNativeTypeMarshallingGenerator
(
marshallingStrategy
,
enableByValueContentsMarshalling
:
false
);
// Elements in the collection must be blittable to use the pinnable marshaller.
...
...
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs
浏览文件 @
b4dd16b4
...
...
@@ -117,14 +117,21 @@ private static bool TryRehydrateMarshalAsAttribute(TypePositionInfo info, out At
{
CountInfo
countInfo
;
MarshallingInfo
elementMarshallingInfo
;
if
(
info
.
MarshallingAttributeInfo
is
NativeLinearCollectionMarshallingInfo_V1
collectionMarshalling
&&
collectionMarshalling
.
UseDefaultMarshalling
&&
collectionMarshalling
.
ElementCountInfo
is
NoCountInfo
or
SizeAndParamIndexInfo
&&
collectionMarshalling
.
ElementMarshallingInfo
is
NoMarshallingInfo
or
MarshalAsInfo
{
UnmanagedType
:
not
UnmanagedType
.
CustomMarshaler
}
)
if
(
info
.
MarshallingAttributeInfo
is
NativeLinearCollectionMarshallingInfo
collectionMarshalling
&&
collectionMarshalling
.
ElementCountInfo
is
NoCountInfo
or
SizeAndParamIndexInfo
)
{
countInfo
=
collectionMarshalling
.
ElementCountInfo
;
elementMarshallingInfo
=
collectionMarshalling
.
ElementMarshallingInfo
;
CustomTypeMarshallerData
defaultMarshallerData
=
collectionMarshalling
.
Marshallers
.
GetModeOrDefault
(
MarshalMode
.
Default
);
if
((
defaultMarshallerData
.
MarshallerType
.
FullTypeName
.
StartsWith
(
$"
{
TypeNames
.
System_Runtime_InteropServices_ArrayMarshaller
}
<"
)
||
defaultMarshallerData
.
MarshallerType
.
FullTypeName
.
StartsWith
(
$"
{
TypeNames
.
System_Runtime_InteropServices_PointerArrayMarshaller
}
<"
))
&&
defaultMarshallerData
.
CollectionElementMarshallingInfo
is
NoMarshallingInfo
or
MarshalAsInfo
{
UnmanagedType
:
not
UnmanagedType
.
CustomMarshaler
})
{
countInfo
=
collectionMarshalling
.
ElementCountInfo
;
elementMarshallingInfo
=
defaultMarshallerData
.
CollectionElementMarshallingInfo
;
}
else
{
return
false
;
}
}
else
if
(
info
.
MarshallingAttributeInfo
is
MissingSupportCollectionMarshallingInfo
missingSupport
)
{
...
...
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StatefulMarshallingStrategy.cs
浏览文件 @
b4dd16b4
...
...
@@ -575,7 +575,7 @@ internal sealed class StatefulLinearCollectionNonBlittableElementsMarshalling :
public
IEnumerable
<
StatementSyntax
>
GenerateMarshalStatements
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToUnmanaged
))
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToUnmanaged
)
&&
!
_shape
.
HasFlag
(
MarshallerShape
.
CallerAllocatedBuffer
)
)
yield
break
;
foreach
(
StatementSyntax
statement
in
_innerMarshaller
.
GenerateMarshalStatements
(
info
,
context
))
...
...
@@ -602,9 +602,6 @@ public IEnumerable<StatementSyntax> GenerateMarshalStatements(TypePositionInfo i
public
IEnumerable
<
StatementSyntax
>
GenerateUnmarshalStatements
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToManaged
))
yield
break
;
string
numElementsIdentifier
=
MarshallerHelpers
.
GetNumElementsIdentifier
(
info
,
context
);
if
(!
info
.
IsByRef
&&
info
.
ByValueContentsMarshalKind
.
HasFlag
(
ByValueContentsMarshalKind
.
Out
))
...
...
@@ -622,6 +619,11 @@ public IEnumerable<StatementSyntax> GenerateUnmarshalStatements(TypePositionInfo
IdentifierName
(
"Length"
)))))));
yield
return
GenerateByValueOutUnmarshalStatement
(
info
,
context
);
}
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToManaged
))
{
yield
break
;
}
else
{
// int <numElements> = <numElementsExpression>;
...
...
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StatelessMarshallingStrategy.cs
浏览文件 @
b4dd16b4
...
...
@@ -59,7 +59,7 @@ public IEnumerable<StatementSyntax> GenerateGuaranteedUnmarshalStatements(TypePo
public
IEnumerable
<
StatementSyntax
>
GenerateMarshalStatements
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToUnmanaged
))
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToUnmanaged
)
&&
!
_shape
.
HasFlag
(
MarshallerShape
.
CallerAllocatedBuffer
)
)
yield
break
;
(
string
managedIdentifier
,
string
nativeIdentifier
)
=
context
.
GetIdentifiers
(
info
);
...
...
@@ -610,9 +610,6 @@ public IEnumerable<StatementSyntax> GenerateSetupStatements(TypePositionInfo inf
public
IEnumerable
<
StatementSyntax
>
GenerateUnmarshalStatements
(
TypePositionInfo
info
,
StubCodeContext
context
)
{
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToManaged
))
yield
break
;
(
string
managedIdentifier
,
string
nativeIdentifier
)
=
context
.
GetIdentifiers
(
info
);
string
numElementsIdentifier
=
MarshallerHelpers
.
GetNumElementsIdentifier
(
info
,
context
);
...
...
@@ -629,6 +626,11 @@ public IEnumerable<StatementSyntax> GenerateUnmarshalStatements(TypePositionInfo
IdentifierName
(
"Length"
))));
yield
return
GenerateByValueOutUnmarshalStatement
(
info
,
context
);
}
if
(!
_shape
.
HasFlag
(
MarshallerShape
.
ToManaged
))
{
yield
break
;
}
else
{
// <numElements> = <numElementsExpression>;
...
...
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs
浏览文件 @
b4dd16b4
...
...
@@ -151,8 +151,7 @@ public enum CustomTypeMarshallerPinning
CustomTypeMarshallers
Marshallers
,
bool
IsPinnableManagedType
,
CountInfo
ElementCountInfo
,
ManagedTypeInfo
PlaceholderTypeParameter
,
bool
UseDefaultMarshalling
)
:
NativeMarshallingAttributeInfo
(
ManagedTypeInfo
PlaceholderTypeParameter
)
:
NativeMarshallingAttributeInfo
(
EntryPointType
,
Marshallers
,
IsPinnableManagedType
);
...
...
@@ -166,7 +165,6 @@ public enum CustomTypeMarshallerPinning
CustomTypeMarshallerDirection
Direction
,
CustomTypeMarshallerFeatures
MarshallingFeatures
,
CustomTypeMarshallerPinning
PinningFeatures
,
bool
UseDefaultMarshalling
,
bool
IsStrictlyBlittable
,
ManagedTypeInfo
?
BufferElementType
,
int
?
BufferSize
)
:
MarshallingInfo
;
...
...
@@ -186,7 +184,6 @@ public enum CustomTypeMarshallerPinning
CustomTypeMarshallerDirection
Direction
,
CustomTypeMarshallerFeatures
MarshallingFeatures
,
CustomTypeMarshallerPinning
PinningFeatures
,
bool
UseDefaultMarshalling
,
int
?
BufferSize
,
CountInfo
ElementCountInfo
,
ManagedTypeInfo
ElementType
,
...
...
@@ -196,7 +193,6 @@ public enum CustomTypeMarshallerPinning
Direction
,
MarshallingFeatures
,
PinningFeatures
,
UseDefaultMarshalling
,
IsStrictlyBlittable
:
false
,
SpecialTypeInfo
.
Byte
,
BufferSize
...
...
@@ -651,8 +647,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
marshallers
.
Value
,
isPinnableManagedType
,
parsedCountInfo
,
ManagedTypeInfo
.
CreateTypeInfoForTypeSymbol
(
entryPointType
.
TypeParameters
.
Last
()),
UseDefaultMarshalling
:
!
isMarshalUsingAttribute
);
ManagedTypeInfo
.
CreateTypeInfoForTypeSymbol
(
entryPointType
.
TypeParameters
.
Last
()));
}
}
else
...
...
@@ -728,7 +723,6 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
customTypeMarshallerData
.
Value
.
Direction
,
customTypeMarshallerData
.
Value
.
Features
,
pinning
,
UseDefaultMarshalling
:
!
isMarshalUsingAttribute
,
customTypeMarshallerData
.
Value
.
BufferSize
,
parsedCountInfo
,
ManagedTypeInfo
.
CreateTypeInfoForTypeSymbol
(
elementType
),
...
...
@@ -740,8 +734,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
nativeType
,
attrData
,
customTypeMarshallerData
.
Value
,
allowPinningManagedType
:
!
isMarshalUsingAttribute
,
useDefaultMarshalling
:
!
isMarshalUsingAttribute
);
allowPinningManagedType
:
!
isMarshalUsingAttribute
);
}
private
MarshallingInfo
CreateNativeMarshallingInfoForValue_V1
(
...
...
@@ -749,8 +742,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
INamedTypeSymbol
nativeType
,
AttributeData
attrData
,
CustomTypeMarshallerData_V1
customTypeMarshallerData
,
bool
allowPinningManagedType
,
bool
useDefaultMarshalling
)
bool
allowPinningManagedType
)
{
ManagedTypeInfo
?
bufferElementTypeInfo
=
null
;
if
(
customTypeMarshallerData
.
Features
.
HasFlag
(
CustomTypeMarshallerFeatures
.
CallerAllocatedBuffer
))
...
...
@@ -790,7 +782,6 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
customTypeMarshallerData
.
Direction
,
customTypeMarshallerData
.
Features
,
pinning
,
useDefaultMarshalling
,
nativeType
.
IsStrictlyBlittable
(),
bufferElementTypeInfo
,
customTypeMarshallerData
.
BufferSize
);
...
...
@@ -938,8 +929,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
marshallers
.
Value
,
IsPinnableManagedType
:
false
,
countInfo
,
ManagedTypeInfo
.
CreateTypeInfoForTypeSymbol
(
arrayMarshaller
.
TypeParameters
.
Last
()),
UseDefaultMarshalling
:
true
);
ManagedTypeInfo
.
CreateTypeInfoForTypeSymbol
(
arrayMarshaller
.
TypeParameters
.
Last
()));
}
}
else
...
...
@@ -965,7 +955,6 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
Direction
:
customTypeMarshallerData
.
Value
.
Direction
,
MarshallingFeatures
:
customTypeMarshallerData
.
Value
.
Features
,
PinningFeatures
:
CustomTypeMarshallerPinning
.
NativeType
,
UseDefaultMarshalling
:
true
,
customTypeMarshallerData
.
Value
.
BufferSize
,
ElementCountInfo
:
countInfo
,
ElementType
:
ManagedTypeInfo
.
CreateTypeInfoForTypeSymbol
(
elementType
),
...
...
@@ -1018,8 +1007,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
stringMarshaller
,
null
,
customTypeMarshallerData
.
Value
,
allowPinningManagedType
:
marshallerName
is
TypeNames
.
Utf16StringMarshaller
,
useDefaultMarshalling
:
false
);
allowPinningManagedType
:
marshallerName
is
TypeNames
.
Utf16StringMarshaller
);
}
private
MarshallingInfo
GetBlittableMarshallingInfo
(
ITypeSymbol
type
)
...
...
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs
浏览文件 @
b4dd16b4
...
...
@@ -58,9 +58,13 @@ public static string MarshalEx(InteropGenerationOptions options)
public
const
string
System_Runtime_InteropServices_MemoryMarshal
=
"System.Runtime.InteropServices.MemoryMarshal"
;
public
const
string
System_Runtime_InteropServices_ArrayMarshaller_Metadata
=
"System.Runtime.InteropServices.Marshalling.ArrayMarshaller`
1
"
;
public
const
string
System_Runtime_InteropServices_ArrayMarshaller_Metadata
=
"System.Runtime.InteropServices.Marshalling.ArrayMarshaller`
2
"
;
public
const
string
System_Runtime_InteropServices_PointerArrayMarshaller_Metadata
=
"System.Runtime.InteropServices.Marshalling.PointerArrayMarshaller`1"
;
public
const
string
System_Runtime_InteropServices_PointerArrayMarshaller_Metadata
=
"System.Runtime.InteropServices.Marshalling.PointerArrayMarshaller`2"
;
public
const
string
System_Runtime_InteropServices_ArrayMarshaller
=
"System.Runtime.InteropServices.Marshalling.ArrayMarshaller"
;
public
const
string
System_Runtime_InteropServices_PointerArrayMarshaller
=
"System.Runtime.InteropServices.Marshalling.PointerArrayMarshaller"
;
public
const
string
System_Runtime_InteropServices_SafeHandle
=
"System.Runtime.InteropServices.SafeHandle"
;
...
...
src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs
浏览文件 @
b4dd16b4
...
...
@@ -2145,26 +2145,39 @@ public static unsafe class AnsiStringMarshaller
public
void
Free
()
{
throw
null
;
}
}
}
[
System
.
CLSCompliantAttribute
(
false
)]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerAttribute
(
typeof
(
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerAttribute
.
GenericPlaceholder
[]),
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerKind
.
LinearCollection
,
BufferSize
=
0x200
,
Features
=
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerFeatures
.
UnmanagedResources
|
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerFeatures
.
CallerAllocatedBuffer
|
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerFeatures
.
TwoStageMarshalling
)]
public
unsafe
ref
struct
ArrayMarshaller
<
T
>
{
public
ArrayMarshaller
(
int
sizeOfNativeElement
)
{
}
public
ArrayMarshaller
(
T
[]?
array
,
int
sizeOfNativeElement
)
{
}
public
ArrayMarshaller
(
T
[]?
array
,
System
.
Span
<
byte
>
buffer
,
int
sizeOfNativeElement
)
{
}
public
System
.
ReadOnlySpan
<
T
>
GetManagedValuesSource
()
{
throw
null
;
}
public
System
.
Span
<
T
>
GetManagedValuesDestination
(
int
length
)
{
throw
null
;
}
public
System
.
ReadOnlySpan
<
byte
>
GetNativeValuesSource
(
int
length
)
{
throw
null
;
}
public
System
.
Span
<
byte
>
GetNativeValuesDestination
()
{
throw
null
;
}
public
ref
byte
GetPinnableReference
()
{
throw
null
;
}
public
byte
*
ToNativeValue
()
{
throw
null
;
}
public
void
FromNativeValue
(
byte
*
value
)
{
}
public
T
[]?
ToManaged
()
{
throw
null
;
}
public
void
FreeNative
()
{
}
[
System
.
CLSCompliant
(
false
)]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomMarshallerAttribute
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
[]),
System
.
Runtime
.
InteropServices
.
Marshalling
.
MarshalMode
.
Default
,
typeof
(
System
.
Runtime
.
InteropServices
.
Marshalling
.
ArrayMarshaller
<,>))]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomMarshallerAttribute
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
[]),
System
.
Runtime
.
InteropServices
.
Marshalling
.
MarshalMode
.
ManagedToUnmanagedIn
,
typeof
(
System
.
Runtime
.
InteropServices
.
Marshalling
.
ArrayMarshaller
<,>.
ManagedToUnmanagedIn
))]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
ContiguousCollectionMarshaller
]
public
static
unsafe
class
ArrayMarshaller
<
T
,
TUnmanagedElement
>
where
TUnmanagedElement
:
unmanaged
{
public
static
TUnmanagedElement
*
AllocateContainerForUnmanagedElements
(
T
[]?
managed
,
out
int
numElements
)
{
throw
null
;
}
public
static
System
.
ReadOnlySpan
<
T
>
GetManagedValuesSource
(
T
[]?
managed
)
{
throw
null
;
}
public
static
System
.
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
{
throw
null
;
}
public
static
T
[]?
AllocateContainerForManagedElements
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
{
throw
null
;
}
public
static
System
.
Span
<
T
>
GetManagedValuesDestination
(
T
[]?
managed
)
{
throw
null
;
}
public
static
System
.
ReadOnlySpan
<
TUnmanagedElement
>
GetUnmanagedValuesSource
(
TUnmanagedElement
*
unmanagedValue
,
int
numElements
)
{
throw
null
;
}
public
static
void
Free
(
TUnmanagedElement
*
unmanaged
)
{
}
public
unsafe
ref
struct
ManagedToUnmanagedIn
{
private
object
_dummy
;
private
int
_dummyPrimitive
;
public
static
int
BufferSize
{
get
{
throw
null
;
}
}
public
void
FromManaged
(
T
[]?
array
,
System
.
Span
<
TUnmanagedElement
>
buffer
)
{
}
public
System
.
ReadOnlySpan
<
T
>
GetManagedValuesSource
()
{
throw
null
;
}
public
System
.
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
()
{
throw
null
;
}
public
ref
TUnmanagedElement
GetPinnableReference
()
{
throw
null
;
}
public
static
ref
T
GetPinnableReference
(
T
[]?
array
)
{
throw
null
;
}
public
TUnmanagedElement
*
ToUnmanaged
()
{
throw
null
;
}
public
void
Free
()
{
}
}
}
[
System
.
CLSCompliant
(
false
)]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomMarshallerAttribute
(
typeof
(
string
),
...
...
@@ -2187,6 +2200,12 @@ public static unsafe class BStrStringMarshaller
public
void
Free
()
{
throw
null
;
}
}
}
[
System
.
AttributeUsageAttribute
(
System
.
AttributeTargets
.
Struct
|
System
.
AttributeTargets
.
Class
)]
public
sealed
partial
class
ContiguousCollectionMarshallerAttribute
:
System
.
Attribute
{
}
[
System
.
AttributeUsageAttribute
(
System
.
AttributeTargets
.
Struct
|
System
.
AttributeTargets
.
Class
,
AllowMultiple
=
true
)]
public
sealed
partial
class
CustomMarshallerAttribute
:
System
.
Attribute
{
...
...
@@ -2264,26 +2283,39 @@ public sealed partial class NativeMarshallingAttribute : System.Attribute
public
NativeMarshallingAttribute
(
System
.
Type
nativeType
)
{
}
public
System
.
Type
NativeType
{
get
{
throw
null
;
}
}
}
[
System
.
CLSCompliantAttribute
(
false
)]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerAttribute
(
typeof
(
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerAttribute
.
GenericPlaceholder
*[]),
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerKind
.
LinearCollection
,
BufferSize
=
0x200
,
Features
=
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerFeatures
.
UnmanagedResources
|
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerFeatures
.
CallerAllocatedBuffer
|
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomTypeMarshallerFeatures
.
TwoStageMarshalling
)]
public
unsafe
ref
struct
PointerArrayMarshaller
<
T
>
where
T
:
unmanaged
{
public
PointerArrayMarshaller
(
int
sizeOfNativeElement
)
{
}
public
PointerArrayMarshaller
(
T
*[]?
array
,
int
sizeOfNativeElement
)
{
}
public
PointerArrayMarshaller
(
T
*[]?
array
,
System
.
Span
<
byte
>
buffer
,
int
sizeOfNativeElement
)
{
}
public
System
.
ReadOnlySpan
<
IntPtr
>
GetManagedValuesSource
()
{
throw
null
;
}
public
System
.
Span
<
IntPtr
>
GetManagedValuesDestination
(
int
length
)
{
throw
null
;
}
public
System
.
ReadOnlySpan
<
byte
>
GetNativeValuesSource
(
int
length
)
{
throw
null
;
}
public
System
.
Span
<
byte
>
GetNativeValuesDestination
()
{
throw
null
;
}
public
ref
byte
GetPinnableReference
()
{
throw
null
;
}
public
byte
*
ToNativeValue
()
{
throw
null
;
}
public
void
FromNativeValue
(
byte
*
value
)
{
}
public
T
*[]?
ToManaged
()
{
throw
null
;
}
public
void
FreeNative
()
{
}
[
System
.
CLSCompliant
(
false
)]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomMarshallerAttribute
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
*[]),
System
.
Runtime
.
InteropServices
.
Marshalling
.
MarshalMode
.
Default
,
typeof
(
System
.
Runtime
.
InteropServices
.
Marshalling
.
PointerArrayMarshaller
<,>))]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomMarshallerAttribute
(
typeof
(
CustomMarshallerAttribute
.
GenericPlaceholder
*[]),
System
.
Runtime
.
InteropServices
.
Marshalling
.
MarshalMode
.
ManagedToUnmanagedIn
,
typeof
(
System
.
Runtime
.
InteropServices
.
Marshalling
.
PointerArrayMarshaller
<,>.
ManagedToUnmanagedIn
))]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
ContiguousCollectionMarshaller
]
public
static
unsafe
class
PointerArrayMarshaller
<
T
,
TUnmanagedElement
>
where
T
:
unmanaged
where
TUnmanagedElement
:
unmanaged
{
public
static
TUnmanagedElement
*
AllocateContainerForUnmanagedElements
(
T
*[]?
managed
,
out
int
numElements
)
{
throw
null
;
}
public
static
System
.
ReadOnlySpan
<
IntPtr
>
GetManagedValuesSource
(
T
*[]?
managed
)
{
throw
null
;
}
public
static
System
.
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
{
throw
null
;
}
public
static
T
*[]?
AllocateContainerForManagedElements
(
TUnmanagedElement
*
unmanaged
,
int
numElements
)
{
throw
null
;
}
public
static
System
.
Span
<
IntPtr
>
GetManagedValuesDestination
(
T
*[]?
managed
)
{
throw
null
;
}
public
static
System
.
ReadOnlySpan
<
TUnmanagedElement
>
GetUnmanagedValuesSource
(
TUnmanagedElement
*
unmanagedValue
,
int
numElements
)
{
throw
null
;
}
public
static
void
Free
(
TUnmanagedElement
*
unmanaged
)
{
}
public
unsafe
ref
struct
ManagedToUnmanagedIn
{
private
object
_dummy
;
private
int
_dummyPrimitive
;
public
static
int
BufferSize
{
get
{
throw
null
;
}
}
public
void
FromManaged
(
T
*[]?
array
,
System
.
Span
<
TUnmanagedElement
>
buffer
)
{
}
public
System
.
ReadOnlySpan
<
IntPtr
>
GetManagedValuesSource
()
{
throw
null
;
}
public
System
.
Span
<
TUnmanagedElement
>
GetUnmanagedValuesDestination
()
{
throw
null
;
}
public
ref
TUnmanagedElement
GetPinnableReference
()
{
throw
null
;
}
public
static
ref
byte
GetPinnableReference
(
T
*[]?
array
)
{
throw
null
;
}
public
TUnmanagedElement
*
ToUnmanaged
()
{
throw
null
;
}
public
void
Free
()
{
}
}
}
[
System
.
CLSCompliant
(
false
)]
[
System
.
Runtime
.
InteropServices
.
Marshalling
.
CustomMarshallerAttribute
(
typeof
(
string
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录