| // Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // SharedObjects=ffi_test_functions |
| |
| // @dart=3.5 |
| |
| import 'dart:ffi'; |
| import 'dart:typed_data'; |
| |
| import 'package:expect/expect.dart'; |
| |
| import 'dylib_utils.dart'; |
| |
| // In both below native methods, the expecting parameters are |
| // SumFirstTwoElements(Pointer<Array<Int32>> (which is also Pointer<Int32>)) |
| // SumTwoElements(a: Pointer<Int32>, b: Pointer<Int32) |
| // but we are intentionally setting to |
| // Pointer<Void> to test .address.cast() |
| |
| @Native<Int32 Function(Pointer<Void>)>( |
| symbol: "SumFirstTwoElements", isLeaf: true) |
| external int sumFirstTwoElements(Pointer<Void> a); |
| |
| @Native<Int32 Function(Pointer<Void>, Pointer<Void>)>( |
| symbol: "SumTwoPointers", isLeaf: true) |
| external int sumTwoPointers(Pointer<Void> a, Pointer<Void> b); |
| |
| void testStructField() { |
| final myStruct = Struct.create<MyStruct>(); |
| |
| myStruct.arr1[0] = 3424; |
| myStruct.arr2[1] = 1000; |
| |
| final expectedArr1 = myStruct.arr1[0] + myStruct.arr1[1]; |
| |
| final arr1SumFirstTwoElements = |
| sumFirstTwoElements(myStruct.arr1.address.cast()); |
| Expect.equals(arr1SumFirstTwoElements, expectedArr1); |
| |
| final arr1SumTwoPointers = sumTwoPointers( |
| myStruct.arr1[0].address.cast(), myStruct.arr1[1].address.cast()); |
| Expect.equals(arr1SumTwoPointers, expectedArr1); |
| |
| myStruct.arr2[0] = 10; |
| myStruct.arr2[1] = 100001; |
| |
| final expectedArr2 = myStruct.arr2[0] + myStruct.arr2[1]; |
| |
| final arr2SumFirstTwoElements = |
| sumFirstTwoElements(myStruct.arr2.address.cast()); |
| Expect.equals(arr2SumFirstTwoElements, expectedArr2); |
| |
| final arr2SumTwoPointers = sumTwoPointers( |
| myStruct.arr2[0].address.cast(), myStruct.arr2[1].address.cast()); |
| Expect.equals(arr2SumTwoPointers, expectedArr2); |
| |
| myStruct.value1 = 22; |
| myStruct.value2 = 3222; |
| |
| final expectedStructValueSum = myStruct.value1 + myStruct.value2; |
| |
| final structValueSumTwoPointers = sumTwoPointers( |
| myStruct.value1.address.cast(), myStruct.value2.address.cast()); |
| Expect.equals(structValueSumTwoPointers, expectedStructValueSum); |
| } |
| |
| void testUnionField() { |
| final myUnion = Union.create<MyUnion>(); |
| |
| myUnion.arr[0] = 23422; |
| myUnion.arr[1] = 231312; |
| |
| final expected = myUnion.arr[0] + myUnion.arr[1]; |
| |
| final arrSumFirstTwoElements = |
| sumFirstTwoElements(myUnion.arr.address.cast()); |
| Expect.equals(arrSumFirstTwoElements, expected); |
| |
| final arrSumTwoPointers = sumTwoPointers( |
| myUnion.arr[0].address.cast(), myUnion.arr[1].address.cast()); |
| Expect.equals(arrSumTwoPointers, expected); |
| |
| myUnion.value1 = 234522; |
| myUnion.value2 = 3322542; |
| |
| final expectedStructValueSum = myUnion.value1 + myUnion.value2; |
| final structValueSumTwoPointers = sumTwoPointers( |
| myUnion.value1.address.cast(), myUnion.value2.address.cast()); |
| Expect.equals(structValueSumTwoPointers, expectedStructValueSum); |
| } |
| |
| void testTypedData() { |
| final buffer = Int32List.fromList([34241, 42432, 42313]); |
| final expected = buffer[0] + buffer[1]; |
| |
| final bufferSumFirstTwoElements = sumFirstTwoElements(buffer.address.cast()); |
| Expect.equals(bufferSumFirstTwoElements, expected); |
| |
| final bufferSumFirstTwoPointers = |
| sumTwoPointers(buffer[0].address.cast(), buffer[1].address.cast()); |
| Expect.equals(bufferSumFirstTwoPointers, expected); |
| } |
| |
| void main() { |
| dlopenGlobalPlatformSpecific("ffi_test_functions"); |
| testStructField(); |
| testTypedData(); |
| testUnionField(); |
| } |
| |
| final class MyStruct extends Struct { |
| @Int32() |
| external int value1; |
| |
| @Int32() |
| external int value2; |
| |
| @Array<Int32>(2) |
| external Array<Int32> arr1; |
| |
| @Array<Int32>(2) |
| external Array<Int32> arr2; |
| } |
| |
| final class MyUnion extends Union { |
| @Int32() |
| external int value1; |
| |
| @Int32() |
| external int value2; |
| |
| @Array<Int32>(2) |
| external Array<Int32> arr; |
| } |