|
1 |
| -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. |
| 1 | +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. |
2 | 2 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
3 | 3 | #
|
4 | 4 | # The Universal Permissive License (UPL), Version 1.0
|
|
37 | 37 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
38 | 38 | # SOFTWARE.
|
39 | 39 | import ctypes
|
| 40 | +import os.path |
40 | 41 | import struct
|
41 |
| -import sys |
42 | 42 |
|
43 | 43 | from tests.cpyext import CPyExtTestCase, CPyExtType
|
44 | 44 |
|
@@ -126,3 +126,102 @@ def test_buffer(self):
|
126 | 126 | assert buffer.format.startswith(b'>')
|
127 | 127 | assert struct.Struct(buffer.format).size == int_format.size
|
128 | 128 | assert buffer.shape == (2, 2)
|
| 129 | + |
| 130 | +# TODO: GR-60735, we cannot support this without NFI struct by value support |
| 131 | +def ignore_test_custom_libs(): |
| 132 | + # 16B: returned in registers on System V AMD64 ABI |
| 133 | + class MySmallStruct1(ctypes.Structure): |
| 134 | + _fields_ = [("num", ctypes.c_int64), ("str", ctypes.c_char_p)] |
| 135 | + |
| 136 | + # 16B incl. 3B padding: not returned in registers on System V AMD64 ABI because of multiple fields |
| 137 | + class MySmallStruct2(ctypes.Structure): |
| 138 | + _fields_ = [("num", ctypes.c_int32), ("str", ctypes.c_char_p), ("end", ctypes.c_int8)] |
| 139 | + |
| 140 | + class MyLargeStruct(ctypes.Structure): |
| 141 | + _fields_ = [("str", ctypes.c_char_p), |
| 142 | + ("num1", ctypes.c_int32), |
| 143 | + ("num2", ctypes.c_int64), |
| 144 | + ("num3", ctypes.c_double), |
| 145 | + ("num4", ctypes.c_int16), |
| 146 | + ("num5", ctypes.c_int8), |
| 147 | + ("num6", ctypes.c_int32), |
| 148 | + ("num7", ctypes.c_int32)] |
| 149 | + |
| 150 | + from distutils.ccompiler import new_compiler |
| 151 | + import tempfile |
| 152 | + |
| 153 | + cc = new_compiler() |
| 154 | + with tempfile.TemporaryDirectory() as tmp_dir: |
| 155 | + original_cwd = os.getcwd() |
| 156 | + try: |
| 157 | + os.chdir(tmp_dir) |
| 158 | + print(tmp_dir) |
| 159 | + with open('src.c', 'x') as f: |
| 160 | + f.write(""" |
| 161 | + #include <stdint.h> |
| 162 | +
|
| 163 | + typedef struct { |
| 164 | + int32_t num; |
| 165 | + const char *data; |
| 166 | + } MySmallStruct1; |
| 167 | +
|
| 168 | + MySmallStruct1 get_small_struct1() { |
| 169 | + MySmallStruct1 s = {42, "hello world"}; |
| 170 | + return s; |
| 171 | + } |
| 172 | +
|
| 173 | + typedef struct { |
| 174 | + int32_t num; |
| 175 | + const char *data; |
| 176 | + int8_t end; |
| 177 | + } MySmallStruct2; |
| 178 | +
|
| 179 | + MySmallStruct2 get_small_struct2() { |
| 180 | + MySmallStruct2 s = {42, "hello world", 42}; |
| 181 | + return s; |
| 182 | + } |
| 183 | +
|
| 184 | + typedef struct { |
| 185 | + const char *data; |
| 186 | + int32_t num1; |
| 187 | + int64_t num2; |
| 188 | + double num3; |
| 189 | + int16_t num4; |
| 190 | + int8_t num5; |
| 191 | + int32_t num6; |
| 192 | + int32_t num7; |
| 193 | + } MyLargeStruct; |
| 194 | +
|
| 195 | + MyLargeStruct get_large_struct() { |
| 196 | + MyLargeStruct s = {"hello world", 42, 42, 42, 42, 42, 42, 42}; |
| 197 | + return s; |
| 198 | + } |
| 199 | + """) |
| 200 | + cc.compile(['src.c']) |
| 201 | + cc.link_shared_lib(['src.o'], 'myshlib') |
| 202 | + |
| 203 | + ctypes_lib = ctypes.CDLL(os.path.join(tmp_dir, 'libmyshlib.so')) |
| 204 | + |
| 205 | + ctypes_lib.get_small_struct1.argtypes = [] |
| 206 | + ctypes_lib.get_small_struct1.restype = MySmallStruct1 |
| 207 | + result = ctypes_lib.get_small_struct1() |
| 208 | + assert result.num == 42, result.num |
| 209 | + |
| 210 | + ctypes_lib.get_small_struct2.argtypes = [] |
| 211 | + ctypes_lib.get_small_struct2.restype = MySmallStruct2 |
| 212 | + result = ctypes_lib.get_small_struct2() |
| 213 | + assert result.num == 42, result.num |
| 214 | + assert result.end == 42, result.end |
| 215 | + |
| 216 | + ctypes_lib.get_large_struct.argtypes = [] |
| 217 | + ctypes_lib.get_large_struct.restype = MyLargeStruct |
| 218 | + result = ctypes_lib.get_large_struct() |
| 219 | + assert result.num1 == 42 |
| 220 | + assert result.num2 == 42 |
| 221 | + assert result.num3 == 42 |
| 222 | + assert result.num4 == 42 |
| 223 | + assert result.num5 == 42 |
| 224 | + assert result.num6 == 42 |
| 225 | + assert result.num7 == 42 |
| 226 | + finally: |
| 227 | + os.chdir(original_cwd) |
0 commit comments