未验证 提交 414e1a74 编写于 作者: F Fan Yang 提交者: GitHub

Fix offset calculation for nested struct, when pinvoke is enabled (#91422)

上级 483490d4
......@@ -355,7 +355,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g
g_assert(info);
for (guint32 i = 0; i < info->num_fields; ++i) {
if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type)) {
collect_field_info_nested (mono_class_from_mono_type_internal (info->fields [i].field->type), fields_array, info->fields [i].offset, pinvoke, unicode);
collect_field_info_nested (mono_class_from_mono_type_internal (info->fields [i].field->type), fields_array, (offset + info->fields [i].offset), pinvoke, unicode);
} else {
guint32 align;
StructFieldInfo f;
......@@ -365,7 +365,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g
info->fields [i].mspec,
&align, TRUE, unicode);
f.offset = offset + info->fields [i].offset;
if (i == info->num_fields - 1 && f.size + f.offset < info->native_size) {
if ((i == info->num_fields - 1) && ((f.size + f.offset) < info->native_size)) {
/* This can happen with .pack directives eg. 'fixed' arrays */
if (MONO_TYPE_IS_PRIMITIVE (f.type)) {
/* Replicate the last field to fill out the remaining place, since the code in add_valuetype () needs type information */
......
// 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.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Text;
public unsafe partial struct GameControllerButtonBind
{
public GameControllerButtonBind
(
GameControllerBindType? bindType = null,
GameControllerButtonBindValue? value = null
) : this()
{
if (bindType is not null)
{
BindType = bindType.Value;
}
if (value is not null)
{
Value = value.Value;
}
}
public GameControllerBindType BindType;
public GameControllerButtonBindValue Value;
}
public enum GameControllerBindType : int
{
ControllerBindtypeNone = 0x0,
ControllerBindtypeButton = 0x1,
ControllerBindtypeAxis = 0x2,
ControllerBindtypeHat = 0x3,
None = 0x0,
Button = 0x1,
Axis = 0x2,
Hat = 0x3,
}
[StructLayout(LayoutKind.Explicit)]
public unsafe partial struct GameControllerButtonBindValue
{
[FieldOffset(0)]
public int Button;
[FieldOffset(0)]
public int Axis;
[FieldOffset(0)]
public GameControllerButtonBindValueHat Hat;
}
public unsafe partial struct GameControllerButtonBindValueHat
{
public int Hat;
public int HatMask;
}
......@@ -1297,3 +1297,8 @@ extern "C" DLL_EXPORT Int32CLongStruct STDMETHODCALLTYPE AddCLongs(Int32CLongStr
{
return { lhs.i + rhs.i, lhs.l + rhs.l };
}
extern "C" DLL_EXPORT SDL_GameControllerBindType STDMETHODCALLTYPE getBindType(SDL_GameControllerButtonBind button)
{
return button.bindType;
}
......@@ -974,3 +974,26 @@ struct Int32CLongStruct
int32_t i;
long l;
};
typedef enum
{
SDL_CONTROLLER_BINDTYPE_NONE = 0,
SDL_CONTROLLER_BINDTYPE_BUTTON,
SDL_CONTROLLER_BINDTYPE_AXIS,
SDL_CONTROLLER_BINDTYPE_HAT
} SDL_GameControllerBindType;
typedef struct SDL_GameControllerButtonBind
{
SDL_GameControllerBindType bindType;
union
{
int button;
int axis;
struct {
int hat;
int hat_mask;
} hat;
} value;
} SDL_GameControllerButtonBind;
// 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.Runtime.InteropServices;
using Xunit;
public class Managed
{
[DllImport("MarshalStructAsParam")]
static extern GameControllerBindType getBindType (GameControllerButtonBind button);
public static int Main()
{
GameControllerButtonBind button = new GameControllerButtonBind(GameControllerBindType.ControllerBindtypeAxis, null);
if (getBindType(button) == GameControllerBindType.ControllerBindtypeAxis)
{
Console.WriteLine("\nTEST PASSED!");
return 100;
}
else
{
Console.WriteLine("\nTEST FAILED!");
return 1;
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="NestedStruct.cs" />
<Compile Include="GameControllerButtonBind.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
<CMakeProjectReference Include="CMakeLists.txt" />
</ItemGroup>
</Project>
......@@ -4062,6 +4062,9 @@
<ExcludeList Include="$(XunitTestBinBase)/Interop/MonoAPI/**">
<Issue>mobile and wasm don't support tests with native libraries. wasm also needs static linking</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/StructMarshalling/PInvoke/NestedStruct/**">
<Issue>https://github.com/dotnet/runtime/issues/64127</Issue>
</ExcludeList>
</ItemGroup>
<Target Name="GetFilteredExcludeList" Returns="@(FilteredExcludeList)">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册