Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
7843caeb
Kaydet (Commit)
7843caeb
authored
Eyl 16, 2018
tarafından
Vladimir Matveev
Kaydeden (comit)
Victor Stinner
Eyl 16, 2018
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-34603, ctypes/libffi_msvc: Fix returning structs from functions (GH-9258)
üst
10a428b6
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
240 additions
and
6 deletions
+240
-6
test_win32.py
Lib/ctypes/test/test_win32.py
+18
-0
2018-09-13-08-29-04.bpo-34603.2AB7sc.rst
...S.d/next/Windows/2018-09-13-08-29-04.bpo-34603.2AB7sc.rst
+1
-0
_ctypes_test.c
Modules/_ctypes/_ctypes_test.c
+194
-0
callproc.c
Modules/_ctypes/callproc.c
+2
-2
ffi.c
Modules/_ctypes/libffi_msvc/ffi.c
+17
-2
ffi.h
Modules/_ctypes/libffi_msvc/ffi.h
+3
-0
prep_cif.c
Modules/_ctypes/libffi_msvc/prep_cif.c
+5
-2
No files found.
Lib/ctypes/test/test_win32.py
Dosyayı görüntüle @
7843caeb
...
...
@@ -54,6 +54,24 @@ class FunctionCallTestCase(unittest.TestCase):
windll
.
user32
.
GetDesktopWindow
()
@unittest.skipUnless
(
sys
.
platform
==
"win32"
,
'Windows-specific test'
)
class
ReturnStructSizesTestCase
(
unittest
.
TestCase
):
def
test_sizes
(
self
):
dll
=
CDLL
(
_ctypes_test
.
__file__
)
for
i
in
range
(
1
,
11
):
fields
=
[
(
f
"f{f}"
,
c_char
)
for
f
in
range
(
1
,
i
+
1
)]
class
S
(
Structure
):
_fields_
=
fields
f
=
getattr
(
dll
,
f
"TestSize{i}"
)
f
.
restype
=
S
res
=
f
()
for
i
,
f
in
enumerate
(
fields
):
value
=
getattr
(
res
,
f
[
0
])
expected
=
bytes
([
ord
(
'a'
)
+
i
])
self
.
assertEquals
(
value
,
expected
)
@unittest.skipUnless
(
sys
.
platform
==
"win32"
,
'Windows-specific test'
)
class
TestWintypes
(
unittest
.
TestCase
):
def
test_HWND
(
self
):
...
...
Misc/NEWS.d/next/Windows/2018-09-13-08-29-04.bpo-34603.2AB7sc.rst
0 → 100644
Dosyayı görüntüle @
7843caeb
Fix returning structs from functions produced by MSVC
Modules/_ctypes/_ctypes_test.c
Dosyayı görüntüle @
7843caeb
...
...
@@ -660,6 +660,200 @@ EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
*
pj
+=
b
;
}
#ifdef MS_WIN32
typedef
struct
{
char
f1
;
}
Size1
;
typedef
struct
{
char
f1
;
char
f2
;
}
Size2
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
}
Size3
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
char
f4
;
}
Size4
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
char
f4
;
char
f5
;
}
Size5
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
char
f4
;
char
f5
;
char
f6
;
}
Size6
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
char
f4
;
char
f5
;
char
f6
;
char
f7
;
}
Size7
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
char
f4
;
char
f5
;
char
f6
;
char
f7
;
char
f8
;
}
Size8
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
char
f4
;
char
f5
;
char
f6
;
char
f7
;
char
f8
;
char
f9
;
}
Size9
;
typedef
struct
{
char
f1
;
char
f2
;
char
f3
;
char
f4
;
char
f5
;
char
f6
;
char
f7
;
char
f8
;
char
f9
;
char
f10
;
}
Size10
;
EXPORT
(
Size1
)
TestSize1
()
{
Size1
f
;
f
.
f1
=
'a'
;
return
f
;
}
EXPORT
(
Size2
)
TestSize2
()
{
Size2
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
return
f
;
}
EXPORT
(
Size3
)
TestSize3
()
{
Size3
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
return
f
;
}
EXPORT
(
Size4
)
TestSize4
()
{
Size4
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
f
.
f4
=
'd'
;
return
f
;
}
EXPORT
(
Size5
)
TestSize5
()
{
Size5
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
f
.
f4
=
'd'
;
f
.
f5
=
'e'
;
return
f
;
}
EXPORT
(
Size6
)
TestSize6
()
{
Size6
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
f
.
f4
=
'd'
;
f
.
f5
=
'e'
;
f
.
f6
=
'f'
;
return
f
;
}
EXPORT
(
Size7
)
TestSize7
()
{
Size7
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
f
.
f4
=
'd'
;
f
.
f5
=
'e'
;
f
.
f6
=
'f'
;
f
.
f7
=
'g'
;
return
f
;
}
EXPORT
(
Size8
)
TestSize8
()
{
Size8
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
f
.
f4
=
'd'
;
f
.
f5
=
'e'
;
f
.
f6
=
'f'
;
f
.
f7
=
'g'
;
f
.
f8
=
'h'
;
return
f
;
}
EXPORT
(
Size9
)
TestSize9
()
{
Size9
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
f
.
f4
=
'd'
;
f
.
f5
=
'e'
;
f
.
f6
=
'f'
;
f
.
f7
=
'g'
;
f
.
f8
=
'h'
;
f
.
f9
=
'i'
;
return
f
;
}
EXPORT
(
Size10
)
TestSize10
()
{
Size10
f
;
f
.
f1
=
'a'
;
f
.
f2
=
'b'
;
f
.
f3
=
'c'
;
f
.
f4
=
'd'
;
f
.
f5
=
'e'
;
f
.
f6
=
'f'
;
f
.
f7
=
'g'
;
f
.
f8
=
'h'
;
f
.
f9
=
'i'
;
f
.
f10
=
'j'
;
return
f
;
}
#endif
#ifdef MS_WIN32
EXPORT
(
S2H
)
__stdcall
s_ret_2h_func
(
S2H
inp
)
{
return
ret_2h_func
(
inp
);
}
EXPORT
(
S8I
)
__stdcall
s_ret_8i_func
(
S8I
inp
)
{
return
ret_8i_func
(
inp
);
}
...
...
Modules/_ctypes/callproc.c
Dosyayı görüntüle @
7843caeb
...
...
@@ -715,9 +715,9 @@ ffi_type *_ctypes_get_ffi_type(PyObject *obj)
It returns small structures in registers
*/
if
(
dict
->
ffi_type_pointer
.
type
==
FFI_TYPE_STRUCT
)
{
if
(
dict
->
ffi_type_pointer
.
size
<=
4
)
if
(
can_return_struct_as_int
(
dict
->
ffi_type_pointer
.
size
)
)
return
&
ffi_type_sint32
;
else
if
(
dict
->
ffi_type_pointer
.
size
<=
8
)
else
if
(
can_return_struct_as_sint64
(
dict
->
ffi_type_pointer
.
size
)
)
return
&
ffi_type_sint64
;
}
#endif
...
...
Modules/_ctypes/libffi_msvc/ffi.c
Dosyayı görüntüle @
7843caeb
...
...
@@ -145,6 +145,21 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
return
;
}
/*
Per: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx
To be returned by value in RAX, user-defined types must have a length
of 1, 2, 4, 8, 16, 32, or 64 bits
*/
int
can_return_struct_as_int
(
size_t
s
)
{
return
s
==
1
||
s
==
2
||
s
==
4
;
}
int
can_return_struct_as_sint64
(
size_t
s
)
{
return
s
==
8
;
}
/* Perform machine dependent cif processing */
ffi_status
ffi_prep_cif_machdep
(
ffi_cif
*
cif
)
{
...
...
@@ -163,9 +178,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* MSVC returns small structures in registers. Put in cif->flags
the value FFI_TYPE_STRUCT only if the structure is big enough;
otherwise, put the 4- or 8-bytes integer type. */
if
(
c
if
->
rtype
->
size
<=
4
)
if
(
c
an_return_struct_as_int
(
cif
->
rtype
->
size
)
)
cif
->
flags
=
FFI_TYPE_INT
;
else
if
(
c
if
->
rtype
->
size
<=
8
)
else
if
(
c
an_return_struct_as_sint64
(
cif
->
rtype
->
size
)
)
cif
->
flags
=
FFI_TYPE_SINT64
;
else
cif
->
flags
=
FFI_TYPE_STRUCT
;
...
...
Modules/_ctypes/libffi_msvc/ffi.h
Dosyayı görüntüle @
7843caeb
...
...
@@ -136,6 +136,9 @@ typedef struct _ffi_type
/*@null@*/
struct
_ffi_type
**
elements
;
}
ffi_type
;
int
can_return_struct_as_int
(
size_t
);
int
can_return_struct_as_sint64
(
size_t
);
/* These are defined in types.c */
extern
ffi_type
ffi_type_void
;
extern
ffi_type
ffi_type_uint8
;
...
...
Modules/_ctypes/libffi_msvc/prep_cif.c
Dosyayı görüntüle @
7843caeb
...
...
@@ -117,7 +117,8 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
/* Make space for the return structure pointer */
if
(
cif
->
rtype
->
type
==
FFI_TYPE_STRUCT
#ifdef _WIN32
&&
(
cif
->
rtype
->
size
>
8
)
/* MSVC returns small structs in registers */
&&
!
can_return_struct_as_int
(
cif
->
rtype
->
size
)
/* MSVC returns small structs in registers */
&&
!
can_return_struct_as_sint64
(
cif
->
rtype
->
size
)
#endif
#ifdef SPARC
&&
(
cif
->
abi
!=
FFI_V9
||
cif
->
rtype
->
size
>
32
)
...
...
@@ -146,7 +147,9 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
bytes
+=
sizeof
(
void
*
);
else
#elif defined (_WIN64)
if
((
*
ptr
)
->
type
==
FFI_TYPE_STRUCT
&&
((
*
ptr
)
->
size
>
8
))
if
((
*
ptr
)
->
type
==
FFI_TYPE_STRUCT
&&
!
can_return_struct_as_int
((
*
ptr
)
->
size
)
&&
!
can_return_struct_as_sint64
((
*
ptr
)
->
size
))
bytes
+=
sizeof
(
void
*
);
else
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment