8000 Handle C long size on Windows. (#497) · sdpython/pythonnet@0ce6301 · GitHub
[go: up one dir, main page]

Skip to content {"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}
This repository was archived by the owner on Jul 22, 2023. It is now read-only.

Commit 0ce6301

Browse files
authored
Handle C long size on Windows. (pythonnet#497)
On Windows 64bit systems, a C `long` is a 32 bit integer while the rest of the world has agreed on making `sizeof(long) == sizeof(void*)`.
1 parent a5f5dc2 commit 0ce6301

File tree

7 files changed

+53
-15
lines changed

7 files changed

+53
-15
lines changed

src/runtime/Python.Runtime.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
<Compile Include="runtime.cs" />
137137
<Compile Include="typemanager.cs" />
138138
<Compile Include="typemethod.cs" />
139+
<Compile Include="Util.cs" />
139140
</ItemGroup>
140141
<ItemGroup Condition=" '$(PythonInteropFile)' != '' ">
141142
<Compile Include="$(PythonInteropFile)" />
@@ -164,4 +165,4 @@
164165
<Copy SourceFiles="$(TargetAssembly)" DestinationFolder="$(PythonBuildDir)" />
165166
<!--Copy SourceFiles="$(TargetAssemblyPdb)" Condition="Exists('$(TargetAssemblyPdb)')" DestinationFolder="$(PythonBuildDir)" /-->
166167
</Target>
167-
</Project>
168+
</Project>

src/runtime/Util.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace Python.Runtime
5+
{
6+
internal class Util
7+
{
8+
internal static Int64 ReadCLong(IntPtr tp, int offset)
9+
{
10+
// On Windows, a C long is always 32 bits.
11+
if (Runtime.IsWindows || Runtime.Is32Bit)
12+
{
13+
return Marshal.ReadInt32(tp, offset);
14+
}
15+
else
16+
{
17+
return Marshal.ReadInt64(tp, offset);
18+
}
19+
}
20+
21+
internal static void WriteCLong(IntPtr type, int offset, Int64 flags)
22+
{
23+
if (Runtime.IsWindows || Runtime.Is32Bit)
24+
{
25+
Marshal.WriteInt32(type, offset, (Int32)(flags & 0xffffffffL));
26+
}
27+
else
28+
{
29+
Marshal.WriteInt64(type, offset, flags);
30+
}
31+
}
32+
}
33+
}

src/runtime/clrobject.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Runtime.InteropServices;
33

44
namespace Python.Runtime
@@ -11,7 +11,7 @@ internal CLRObject(object ob, IntPtr tp)
1111
{
1212
IntPtr py = Runtime.PyType_GenericAlloc(tp, 0);
1313

14-
var flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
14+
long flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
1515
if ((flags & TypeFlags.Subclass) != 0)
1616
{
1717
IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.DictOffset(tp));

src/runtime/managedtype.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Runtime.InteropServices;
33

44
namespace Python.Runtime
@@ -28,7 +28,7 @@ internal static ManagedType GetManagedObject(IntPtr ob)
2828
tp = ob;
2929
}
3030

31-
var flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
31+
var flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
3232
if ((flags & TypeFlags.Managed) != 0)
3333
{
3434
IntPtr op = tp == ob
@@ -63,7 +63,7 @@ internal static bool IsManagedType(IntPtr ob)
6363
tp = ob;
6464
}
6565

66-
var flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
66+
var flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
6767
if ((flags & TypeFlags.Managed) != 0)
6868
{
6969
return true;

src/runtime/metatype.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
105105
flags |= TypeFlags.BaseType;
106106
flags |= TypeFlags.Subclass;
107107
flags |= TypeFlags.HaveGC;
108-
Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
108+
Util.WriteCLong(type, TypeOffset.tp_flags, flags);
109109

110110
TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc);
111111

@@ -237,7 +237,7 @@ public static void tp_dealloc(IntPtr tp)
237237
{
238238
// Fix this when we dont cheat on the handle for subclasses!
239239

240-
var F438 flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
240+
var flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
241241
if ((flags & TypeFlags.Subclass) == 0)
242242
{
243243
IntPtr gc = Marshal.ReadIntPtr(tp, TypeOffset.magic());

src/runtime/runtime.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ public class Runtime
152152
internal static bool IsFinalizing;
153153

154154
internal static bool Is32Bit = IntPtr.Size == 4;
155+
156+
// .NET core: System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
157+
internal static bool IsWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
158+
155159
internal static bool IsPython2 = pyversionnumber < 30;
156160
internal static bool IsPython3 = pyversionnumber >= 30;
157161

@@ -762,7 +766,7 @@ internal static bool PyObject_IsIterable(IntPtr pointer)
762766
{
763767
var ob_type = Marshal.ReadIntPtr(pointer, ObjectOffset.ob_type);
764768
#if PYTHON2
765-
long tp_flags = Marshal.ReadInt64(ob_type, TypeOffset.tp_flags);
769+
long tp_flags = Util.ReadCLong(ob_type, TypeOffset.tp_flags);
766770
if ((tp_flags & TypeFlags.HaveIter) == 0)
767771
return false;
768772
#endif
@@ -1419,7 +1423,7 @@ internal static bool PyIter_Check(IntPtr pointer)
14191423
{
14201424
var ob_type = Marshal.ReadIntPtr(pointer, ObjectOffset.ob_type);
14211425
#if PYTHON2
1422-
long tp_flags = Marshal.ReadInt64(ob_type, TypeOffset.tp_flags);
1426+
long tp_flags = Util.ReadCLong(ob_type, TypeOffset.tp_flags);
14231427
if ((tp_flags & TypeFlags.HaveIter) == 0)
14241428
return false;
14251429
#endif

src/runtime/typemanager.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.Reflection;
@@ -86,7 +86,7 @@ internal static IntPtr CreateType(Type impl)
8686

8787
int flags = TypeFlags.Default | TypeFlags.Managed |
8888
TypeFlags.HeapType | TypeFlags.HaveGC;
89-
Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
89+
Util.WriteCLong(type, TypeOffset.tp_flags, flags);
9090

9191
Runtime.PyType_Ready(type);
9292

@@ -160,7 +160,7 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType)
160160
flags |= TypeFlags.HeapType;
161161
flags |= TypeFlags.BaseType;
162162
flags |= TypeFlags.HaveGC;
163-
Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
163+
Util.WriteCLong(type, TypeOffset.tp_flags, flags);
164164

165165
// Leverage followup initialization from the Python runtime. Note
166166
// that the type of the new type must PyType_Type at the time we
@@ -323,7 +323,7 @@ internal static IntPtr CreateMetaType(Type impl)
323323
flags |= TypeFlags.Managed;
324324
flags |= TypeFlags.HeapType;
325325
flags |= TypeFlags.HaveGC;
326-
Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
326+
Util.WriteCLong(type, TypeOffset.tp_flags, flags);
327327

328328
// We need space for 3 PyMethodDef structs, each of them
329329
// 4 int-ptrs in size.
@@ -380,7 +380,7 @@ internal static IntPtr BasicSubType(string name, IntPtr base_, Type impl)
380380
flags |= TypeFlags.Managed;
381381
flags |= TypeFlags.HeapType;
382382
flags |= TypeFlags.HaveGC;
383-
Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
383+
Util.WriteCLong(type, TypeOffset.tp_flags, flags);
384384

385385
CopySlot(base_, type, TypeOffset.tp_traverse);
386386
CopySlot(base_, type, TypeOffset.tp_clear);

0 commit comments

Comments
 (0)
0